我有一个React组件,在组件的渲染方法中,我有这样的东西:

render() {
    return (
        <div>
            <div>
                // removed for brevity
            </div>

           { switch(...) {} }

            <div>
                // removed for brevity
            </div>
        </div>
    );
}

Now the point is that I have two div elements, one at the top and one at the bottom, that are fixed. In the middle I want to have a switch statement, and according to a value in my state I want to render a different component. So basically, I want the two div elements to be fixed always, and just in the middle to render a different component each time. I'm using this to implement a multi-step payment procedure). Though, as is the code currently it doesn't work, as it gives me an error saying that switch is unexpected. Any ideas how to achieve what I want?


当前回答

我在render()方法中做了这个:

  render() {
    const project = () => {
      switch(this.projectName) {

        case "one":   return <ComponentA />;
        case "two":   return <ComponentB />;
        case "three": return <ComponentC />;
        case "four":  return <ComponentD />;

        default:      return <h1>No project match</h1>
      }
    }

    return (
      <div>{ project() }</div>
    )
  }

我试图保持render()返回干净,所以我把我的逻辑放在一个'const'函数上面。这样我也可以缩进我的开关盒整齐。

其他回答

Lenkan的回答是一个很好的解决方案。

<div>
  {{ beep: <div>Beep</div>,
     boop: <div>Boop</div>
  }[greeting]}
</div>

如果需要一个默认值,那么您甚至可以这样做

<div>
  {{ beep: <div>Beep</div>,
     boop: <div>Boop</div>
  }[greeting] || <div>Hello world</div>}
</div>

或者,如果这对你来说不太好,那么你可以做一些

<div>
  { 
    rswitch(greeting, {
      beep: <div>Beep</div>,
      boop: <div>Boop</div>,
      default: <div>Hello world</div>
    }) 
  }
</div>

with

function rswitch (param, cases) {
  if (cases[param]) {
    return cases[param]
  } else {
    return cases.default
  }
}

这是因为switch语句是一个语句,但这里javascript需要一个表达式。

虽然,不建议在呈现方法中使用switch语句,但你可以使用自调用函数来实现这一点:

render() {
    // Don't forget to return a value in a switch statement
    return (
        <div>
            {(() => {
                switch(...) {}
            })()}
        </div>
    );
}

我们可以直接使用useCallback来做到这一点

const renderContent = useCallback(() => { switch (sortState) { “一”: 返回“一”; “两个”: 返回“两个”; “三”: 返回“三”; “四”: 返回“四”; 默认值: 返回“一”; } }, [sortState]);

这将在jsx中使用

<div>排序:{renderContent()}</div>

  const [route, setRoute] = useState(INITIAL_ROUTE)

  return (
    <RouteContext.Provider value={{ route, setRoute }}>
      {(() => {
        switch (route) {
          case Route.Home:
            return <PopupHomePage />
          case Route.App:
            return <PopupAppPage />
          default:
            return null
        }
      })()}
    </RouteContext.Provider>

尽管这是另一种方法,但如果您已经完全使用了钩子,则可以利用useCallback来生成一个只在必要时重新创建的函数。

假设你有一个组件,它应该根据状态道具来呈现。使用钩子,你可以这样实现:

const MyComponent = ({ status }) => {
  const renderContent = React.useCallback(() => {
    switch(status) {
      case 'CONNECTING': 
        return <p className="connecting">Connecting...</p>;
      
      case 'CONNECTED': 
        return <p className="success">Connected Successfully!</p>

      default: 
        return null;
      
    }
  }, [status]);

  return (
    <div className="container">
      {renderContent()}
    </div>
  );
};

我喜欢这个是因为:

It's obvious what is going on - a function is created, and then later called (the immediately invoked anonymous function method looks a little odd, and can potentially confuse newer developers) The useCallback hook ensures that the renderContent callback is reused between renders, unless the depedency status changes The renderContent function uses a closure to access the necessary props passed in to the component. A separate function (like the accepted answer) requires the passing of the props into it, which can be burdensome (especially when using TypeScript, as the parameters should also be typed correctly)