2016-11-30 38 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