【问题标题】:React component only changes state on second onClick eventReact 组件仅在第二个 onClick 事件时更改状态
【发布时间】:2016-02-26 09:10:57
【问题描述】:

我有这两个简化 React 组件,其中Times 组件是Create 组件的子组件(请参阅下面的代码示例)。预期的行为是,最初,Times 组件未显示,但当用户单击带有onClick 的链接时,Times 组件出现。

组件大部分都按预期工作,但奇怪的是,在第一次单击onClick 链接后,Times 组件没有出现,Create 组件根本没有改变状态,因为显示在控制台中。但是,当第二次单击该链接时,Create 组件确实会更改状态并重新渲染,并且会看到 Times 组件。

创建.jsx

import React from 'react';
import Times from './Times.jsx';

export default React.createClass({

  getInitialState: function () {
    return {times: false};
  },

  _change: function () {
    this.replaceState({times: true});
    console.log(this.state.times);
  },

  render: function () {
    return (
      <div id="create">
        <div id="outerbox">
          <a onClick={this._change}>Times</a>
          <Times shouldShow={this.state.times}/>
        </div>
      </div>
    );
  }
});

Times.jsx

import React from 'react';

export default React.createClass({

  propTypes: {
    shouldShow: React.PropTypes.bool.isRequired
  },

  getDefaultProps: function () {
    return {shouldShow: false};
  },

  getInitialState: function () {
    return {el: 'times'};
  },

  componentDidMount: function() {
    if (this.props.shouldShow === false) {
      this.setState({display: 'none'});
    } else {
      this.setState({display: 'block'});
    }
  },

  componentWillReceiveProps: function() {
    if (this.props.shouldShow === false) {
      this.setState({display: 'none'});
    } else {
      this.setState({display: 'block'});
    }
  },

  render: function () {
    return (
      <div id={this.state.el} style={{"display": this.state.display}}>
        <h1>Times</h1>
      </div>
    );
  }
});

console.log 的输出

false
true

为什么Create组件的状态在第一次点击时没有注册?

【问题讨论】:

    标签: javascript reactjs components state


    【解决方案1】:

    问题就在这里。

     componentWillReceiveProps: function() {
        if (this.props.shouldShow === false) {
          this.setState({display: 'none'});
        } else {
          this.setState({display: 'block'});
        }
      }
    

    应该是这样的,

     componentWillReceiveProps: function(newProps) {
        if (newProps.shouldShow === false) {
          this.setState({display: 'none'});
        } else {
          this.setState({display: 'block'});
        }
      }
    

    ComponentWillRecieveProps 是组件类的一个成员函数,它在 props 被“应用”之前被调用。这意味着this.props 是旧的道具。您应该使用 newProps 作为参数提供给函数。

    http://codepen.io/bhargav175/pen/gaJmKz


    另外,我感觉你使用的状态比你需要的多一点。您根本不需要显示作为状态变量。 Times 是一个内部组件,因此尽可能多地使用 props 并使它们无状态是有意义的。

    关于“props 更改不会影响渲染,所以让我们使用 state”有一个常见的误解。道具更改也会导致重新渲染,因此请始终使用道具,除非有充分的理由并且您确实需要使内部组件变得智能。在内部组件中使用道具,使它们变得笨拙且更易于使用。

    http://codepen.io/bhargav175/pen/WQBpzP

       var Times = React.createClass({
    
      propTypes: {
        shouldShow: React.PropTypes.bool.isRequired
      },
    
      getDefaultProps: function () {
        return {shouldShow: false};
      },
    
      getInitialState: function () {
        return {el: 'times'};
      },
    
    
    
      render: function () {
        let display = this.props.shouldShow ? "block" : "none";
        return (
          <div id={this.state.el} style={{"display": display}}>
            <h1>Times</h1>
          </div>
        );
      }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-13
      • 2017-01-12
      • 2021-02-02
      • 2018-09-21
      • 1970-01-01
      相关资源
      最近更新 更多