2016-11-30 54 views
0

我正在尝试学习ReactJS和Redux,并遇到了一个我似乎无法克服的问题。依赖异步请求和状态变化的React渲染方法

我有一个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> 
    ) 
    } 
    } 
} 

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

我想看看这种情况是如何处理的。

谢谢。

+0

如果您使用的终极版..阅读此http://redux.js。 org/docs/advanced/AsyncActions.html ...如果您想使用React组件事件,请尝试返回false直到达到您所需的状态https://facebook.github.io/react/docs/react-component.html#应该更新 –

+1

将此this.setState({enableFeature:event.target.checked})'改为'this.setState((prevState)=>({enableFeature:!prevState.enableFeature}))' –

回答

2

尝试做像下面,即

  1. 使用componentWillReceiveProps分配props.enableFeature到state.enableFeature。从文档

componentWillReceiveProps()一个安装组件接收新道具之前被调用。如果您需要更新状态以响应prop更改(例如,重置它),您可以比较this.props和nextProps,并在此方法中使用this.setState()执行状态转换。

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

componentWillReceiveProps()没有被调用,如果你只需调用this.setState()

  • 使用此状态加载复选框的值

  • 操作此状态(onchange)以更新复选框的值

  • 以下代码可以工作你的情况

    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>); 
        } 
    } 
    

    注:上面的代码被执行,而是应该工作(巴别塔的0级代码)

    +0

    非常感谢Ammar! – rookieRailer

    1

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

    +0

    我也试过。但是这仍然没有帮助。 基本上,当'render'方法被调用(它被多次调用)时,复选框状态被设置。但是,当调用'onChange'方法时,它会重新呈现组件,因为'shouldComponentUpdate'返回true,然后它将复选框的状态设置回原来的状态。 解决方案可能是一种回调方法,我可以在后端API请求完成时将组件'state'设置为与组件'props'同步,以便第一次正确设置复选框状态。 – rookieRailer