【问题标题】:React conditional rendering of multiple child components反应多个子组件的条件渲染
【发布时间】:2018-02-09 20:57:13
【问题描述】:

我正在尝试根据状态渲染多个子组件,但是我只能返回一个子组件(SyntaxError: Adjacent JSX 元素必须包含在封闭标记中)

每个子组件都传递相同的 props,这段代码如何保持 DRY?

作品

export default ({changeState, myState, handleClick}) => (
    <Navigation>
            <span>Navigation</span>
            <button onClick={() => changeState()}>Navigation</button>
            { myState ?
                <NavigationItem handleClick={handleClick} title={'#Link-1'} />
              : null
            }
    </Navigation>
)

不要

export default ({changeState, myState, handleClick}) => (
    <Navigation>
            <h1>Navigation</h1>
            <button onClick={() => changeState()}>Navigation</button>
            { myState ?
                <NavigationItem handleClick={handleClick} title={'#Link-1'} />
                <NavigationItem handleClick={handleClick} title={'#Link-2'} />
                <NavigationItem handleClick={handleClick} title={'#Link-3'} />
              : null
            }
    </Navigation>
)

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    你也可以使用来自 ReactJS 的&lt;Fragment&gt;:https://reactjs.org/docs/fragments.html

    使用&lt;div&gt; 包装所有元素的问题在于,您正在向 DOM 添加更多元素,有时这是不可能的(例如,当您在 @ 内渲染 &lt;td&gt; 或 &lt;tr&gt; 时987654328@。所以,&lt;Fragment&gt; 来帮助我们了。

    只需将所有这些元素包装在 &lt;Fragment&gt; 中就足够了。 含义:

    { myState &&
      <Fragment>
        <NavigationItem handleClick={handleClick} title={'#Link-1'} />
        <NavigationItem handleClick={handleClick} title={'#Link-2'} />
        <NavigationItem handleClick={handleClick} title={'#Link-3'} />
      </Fragment>
    }
    

    无论如何,这另一种“条件渲染”方法在“代码可读性”意义上更好:https://medium.com/@BrodaNoel/conditional-rendering-in-react-and-jsx-the-solution-7c80beba1e36

    它基本上建议使用&lt;Conditional&gt; 元素,例如:

    <Conditional if={myState}>
      <NavigationItem handleClick={handleClick} title={'#Link-1'} />,
      <NavigationItem handleClick={handleClick} title={'#Link-2'} />,
      <NavigationItem handleClick={handleClick} title={'#Link-3'} />
    </Conditional>
    

    ^ 这看起来更适合我的眼睛:D

    【讨论】:

    • Conditional 组件似乎是一个不必要的抽象,它添加了更多样板代码:( 我觉得人们用他们的“智能抽象”太努力了。现实是,人们不知道你的抽象是什么确实如此,但大多数程序员都知道基本的 JS 语法……当您将该代码移到一个单独的项目中时,情况会变得更糟,现在人们必须实际进入该项目才能看到它为什么不起作用。
    • @Doug 是的,我同意。我总是只使用{!!var &amp;&amp; &lt;div /&gt;}。但有时(某些团队)要求一切都必须是声明性的,因此他们使用这种行为。有时他们必须这样做,因为有一些动态代码生成,以及其他一些魔法/yerbas。
    • Fragment 的短 syntax 使代码更具可读性。但是,并非所有工具都支持它。
    • @Sourabh 是的。当 Fragment 的语法很短时,即使是 Github 也会破坏所有颜色。
    • 我认为&lt;Conditional&gt; 组件概念是一个很好的概念。 React 应该像 Vue.js 那样开箱即用。
    【解决方案2】:

    直接我们不能返回多个元素。

    可能的解决方案:

    1- 您需要将所有元素包装在 div 或任何其他包装元素中。

    2-我们也可以返回一个包含多个元素的数组,所以把所有的元素放在一个数组中,然后返回数组。

    像这样:

    {myState ?
        [
            <NavigationItem handleClick={handleClick} title={'#Link-1'} />,
            <NavigationItem handleClick={handleClick} title={'#Link-2'} />,
            <NavigationItem handleClick={handleClick} title={'#Link-3'} />
        ]
      : null
    }
    

    检查这个例子:

    let b = true ? [1,2,3,4]: null;
    
    console.log('b = ', b);

    这会抛出错误:

    let b = true? 1 2 3 4: null;
    
    console.log('b = ', b);

    【讨论】:

    • 谢谢,{myState &amp;&amp; ...} 语法非常方便。
    猜你喜欢
    • 2020-07-31
    • 1970-01-01
    • 2017-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 2019-03-25
    • 2021-05-01
    相关资源
    最近更新 更多