我有一个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?


当前回答

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

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

这将在jsx中使用

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

其他回答

你不能在渲染中有开关。放置访问一个元素的对象文字的伪切换方法并不理想,因为它会导致所有视图都要处理,并且可能导致在该状态下不存在的道具的依赖错误。

这里有一个很好的干净的方法来做到这一点,不需要每个视图提前渲染:

render () {
  const viewState = this.getViewState();

  return (
    <div>
      {viewState === ViewState.NO_RESULTS && this.renderNoResults()}
      {viewState === ViewState.LIST_RESULTS && this.renderResults()}
      {viewState === ViewState.SUCCESS_DONE && this.renderCompleted()}
    </div>
  )

如果视图状态的条件不只基于一个简单的属性——比如每行有多个条件,那么枚举和getViewState函数封装条件是分离条件逻辑和清理呈现的好方法。

这个答案专门用来解决@tonyfat提出的“重复”问题,关于如何使用条件表达式来处理相同的任务。


Avoiding statements here seems like more trouble than it's worth, but this script does the job as the snippet demonstrates:

// Runs tests let id = 0, flag = 0; renderByFlag(id, flag); // jobId out of range id = 1; // jobId in range while(++flag < 5){ // active flag ranges from 1 to 4 renderByFlag(id, flag); } // Defines a function that chooses what to render based on two provided values function renderByFlag(jobId, activeFlag){ jobId === 1 ? ( activeFlag === 1 ? render("A (flag = 1)") : activeFlag === 2 ? render("B (flag = 2)") : activeFlag === 3 ? render("C (flag = 3)") : pass(`flag ${activeFlag} out of range`) ) : pass(`jobId ${jobId} out of range`) } // Defines logging functions for demo purposes function render(val){ console.log(`Rendering ${val}`); } function pass(reason){ console.log(`Doing nothing (${reason})`) }

尽管这是另一种方法,但如果您已经完全使用了钩子,则可以利用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)

与其他答案相比,我更倾向于在渲染函数中内联“开关”。它使什么组件可以在那个位置呈现更清楚。你可以使用一个简单的javascript对象来实现一个类似switch的表达式:

render () {
  return (
    <div>
      <div>
        {/* removed for brevity */}
      </div>
      {
        {
          'foo': <Foo />,
          'bar': <Bar />
        }[param]
      }
      <div>
        {/* removed for brevity */}
      </div>
    </div>
  )
}

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

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

这将在jsx中使用

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