React渲染方法依赖于异步请求和状态更改

时间:2016-11-30 13:11:33

标签: javascript reactjs redux

我正在尝试学习ReactJS和Redux,并遇到了一个我似乎无法克服的问题。

我有一个React组件,它从异步请求中获取数据。

export class MyPage extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      enableFeature: false,
    }

    this.handleEnableFeatureChange = this.handleEnableFeatureChange.bind(this)
  } 

  componentWillMount () {
    this.fetchData()
  }

  fetchData () {
    let token = this.props.token
    this.props.actions.fetchData(token)
  }

  handleEnableFeatureChange (event) {
    this.setState({ enableFeature: event.target.checked })
  }

  render () {
    if (this.props.isFetching) {
      return (
        <div>Loading...</div>
      )
    } else {
      return (
        <div>
          <label>Enable Feature
              <input type="checkbox"
                className="form-control"
                checked={this.props.enableFeature}
                onChange={this.handleEnableFeatureChange}
              />
          </label>
        </div>
      )
    }
  }
}

所以,我现在的问题是,当我更改复选框的状态时,我想更新数据的状态。但是,每次更新数据状态时,react组件方法shouldComponentUpdate都会启动,并使用当前的props来呈现原始数据。

我想看看这些案件的处理方式一般。

感谢。

2 个答案:

答案 0 :(得分:2)

尝试按照以下方式进行,即

  1. 使用componentWillReceiveProps将props.enableFeature分配给state.enableFeature。来自文档
  2.   在挂载的组件接收新道具之前调用

    componentWillReceiveProps()。如果您需要更新状态以响应道具更改(例如,重置它),您可以比较this.props和nextProps并在此方法中使用this.setState()执行状态转换。

         

    请注意,即使道具没有更改,React也可以调用此方法,因此如果您只想处理更改,请确保比较当前值和下一个值。当父组件可能会发生这种情况导致组件重新渲染。

         如果你只是调用this.setState()

    ,则不会调用

    componentWillReceiveProps()

    1. 使用此状态加载复选框

    2. 的值
    3. 操纵此状态(onchange)以更新复选框

    4. 的值

      以下代码可以适用于您的情况

      export class MyPage extends React.Component {
        static propTypes = {
          isFetching: React.PropTypes.bool,
          enableFeature: React.PropTypes.bool,
          token: React.PropTypes.string,
          actions: React.PropTypes.shape({
            fetchData: React.PropTypes.func
          })
        };
      
        state = {
          enableFeature: false,
        };
      
        componentWillMount () {
          this.fetchData();
        }
      
        /* Assign received prop to state, so that this state can be used in render */
        componentWillReceiveProps(nextProps) {
          if (this.props.isFetching && !nextProps.isFetching) {
            this.state.enableFeature = nextProps.enableFeature;
          }
        }
      
        fetchData () {
          const { token } = this.props;
          this.props.actions.fetchData(token)
        }
      
        handleEnableFeatureChange = (event) => {
          this.setState({ enableFeature: event.target.checked })
        };
      
        render () {
          return (<div>
            { this.props.isFetching && "Loading..." }
            { 
              !this.props.isFetching && <label>
                Enable Feature
                <input 
                  type="checkbox"
                  className="form-control"
                  checked={this.state.enableFeature}
                  onChange={this.handleEnableFeatureChange}
                />
              </label> 
            }
          </div>);
        }
      }
      

      注意:以上代码未执行,但应该有效(babel的第0阶段代码)

答案 1 :(得分:1)

将其更改为checked={this.state.enableFeature}