【问题标题】:React rendering content before props is properly mapped / set在正确映射/设置道具之前反应渲染内容
【发布时间】:2018-09-01 12:55:46
【问题描述】:

我使用 Redux 创建了一个带有 React 的组件,它在状态映射到 props 之前需要两次渲染。

使用此代码,

'user.private' 在第一次渲染时为空,在第二次渲染时为假

因此,在显示隐藏内容之前,加载页面会在显示“登录”之间闪烁一秒钟

我想默认显示登录文本,但如果用户的私有字段设置为 false,我实际上不希望它显示。

class Content extends React.Component {
    render() {
        const { user } = this.props;

        let show = false;

        if (user.private === false) show = true

        return (
            <section>
            {
                show
                ? <p>hidden content</p>  
                : <p>login</p>
            }
            </section>  
        )
    }
}

const mapStateToProps = state => ({
  user: state.store.user
});

export default connect(mapStateToProps, {})(Content)

【问题讨论】:

  • if (!user.private) show = true ?
  • 产生同样的效果

标签: reactjs react-redux


【解决方案1】:

假设 user 最初未定义或为 null,您可以在显示任何内容之前检查 user 和/或其属性 private 是否已定义:

if (this.props.user == null || this.props.user.private) {
  show = false;
}

如果this.props.user 的值未定义或为空,double equals null 将使条件为true。你也可以使用!this.props.user

如果您在获得 user 之前将其初始值设为 {},那么您将不得不这样做:

if (this.props.user.private == null || this.props.user.private) {
  show = false;
}

【讨论】:

    【解决方案2】:

    您可以使用 switch 来处理 null 情况(您可以显示加载程序或通过返回 null 不渲染) 我使用组件状态来说明这个想法,但是您可以将其应用于您的 redux 连接组件

    class App extends React.Component {
      state = {
        user : {
          private : null
        }
      }
    
      componentDidMount () {
          setTimeout(() => {
            this.setState(() => {
              return {
                user : {
                  private : true
                }
              }
            });
          }, 2000);
      }
    
      renderContent () {
        const { user } = this.state;
        switch (user.private) {
          case null : return <span>Loading...</span>
          case false : return <p>login</p> 
          default : return <p>hidden content</p> 
        }
      }
    
      render () {
        return (
          <div>
              {this.renderContent()}
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <App/>,
      document.querySelector('#root')
    );
    

    demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-13
      • 1970-01-01
      • 2019-05-11
      • 2019-02-03
      • 2016-09-12
      • 1970-01-01
      • 2017-09-28
      • 2021-01-29
      相关资源
      最近更新 更多