即使使用单个父级和子级列表,也会发生条件渲染错误

时间:2018-03-30 09:06:48

标签: reactjs

学习一点React,但在我看来,React本身就存在一个条件渲染错误。

假设我有一个Foo组件,如下所示:

foo.js

import React, { Component } from 'react';

class Foo extends Component {
  render() {
    const isLoggedIn = this.props.isLoggedIn;

    return(
      <div>
        { isLoggedIn ? (
          <div>one</div><div>two</div>
        ) : (
          <div>one</div><div>two</div><div>three</div>
        )}
      </div>
    );
  }
}

export default Foo;

我这样使用它:

app.js

import React, { Component } from 'react';
import Foo from './components/foo';

class App extends Component {
  render() {
    return (
      <div>
          <Foo isLoggedIn={false} />
      </div>
    );
  }
}

export default App;

这会产生错误:

Syntax error: Adjacent JSX elements must be wrapped in an enclosing tag

请注意上面的Foo组件,只有一个父div返回而不是数组。如果它是一个数组,那么我同意错误。

React文档示例中给出的官方示例如下:

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      {isLoggedIn ? (
        <LogoutButton onClick={this.handleLogoutClick} />
      ) : (
        <LoginButton onClick={this.handleLoginClick} />
      )}
    </div>
  );
}

https://reactjs.org/docs/conditional-rendering.html

对任何人来说,这看起来像是React中的错误吗?

更新

基于这里给出的答案和评论,React的隐含行为是render()函数内部的三元运算符,它在幕后自带render调用,就像虚拟组件一样,意味着需要在我的子元素列表中包含额外的<div>层。

Emberjs Foo组件

我的困惑源于我过去做了一些Emberjs开发的事实,这样的组件按预期工作:

<h3>Foo component</h3>

{{#if isLoggedIn}}
  <div>one</div><div>two</div>
{{else}}
  <div>one</div><div>two</div><div>three</div>
{{/if}}

感谢大家的解释。

5 个答案:

答案 0 :(得分:1)

您有语法错误

          <div>one</div><div>two</div><div>three</div

应该是

          <div>one</div><div>two</div><div>three</div>

答案 1 :(得分:1)

您尝试添加吗?

return(
      <div>
        { isLoggedIn ? (
          <Fragment><div>one</div><div>two</div><Fragment>
        ) : (
          <Fragment><div>one</div><div>two</div><div>three</div><Fragment>
        )}
      </div>
    );

答案 2 :(得分:1)

您正在返回条件中的2或3个div。相反,你应该将它们包装在div上并返回。

请注意下面的包装 div。

{ isLoggedIn ? (
      <div className='wrapper'><div>one</div><div>two</div><div>
    ) : (
      </div className='wrapper'><div>one</div><div>two</div><div>three</div></div>
    )}

另请注意,

下方有小错字
<div>one</div><div>two</div><div>three</div

答案 3 :(得分:1)

  

语法错误:相邻的JSX元素必须包装在一个封闭的标记中吗?

您正以错误的方式返回多个兄弟JSX元素。

在Foo:

return(
      <div>
        { isLoggedIn ? (
          <div>one</div> //are siblings without 
          <div>two</div> //wrapping in container element.
        ) : (
          <div>one</div> //are siblings without 
          <div>two</div> //wrapping in 
          <div>three</div>//container element.
        )}
      </div>
    );

正确方法:

return (
            <div>
                {isLoggedIn
                    ? (
                        <div> //add wrapper
                             /...
                        </div>
                    )
                    : (
                        <div> //add wrapper
                            //...
                        </div>
                    )}
            </div>
        );

或者

如果您使用的是React16,那么您也可以使用React.Fragement

e.g。

<React.Fragment>
  <div>one</div>
  <div>two</div>
</React.Fragment>

答案 4 :(得分:0)

您需要包装在条件

中呈现的元素
return(
  <div>
    { isLoggedIn ? (
      <div><div>one</div><div>two</div></div>
    ) : (
      <div><div>one</div><div>two</div><div>three</div></div>
    )}
  </div>
);

注意嵌套条件元素

周围的额外div