2017-03-08 82 views
1

我有一個react/redux應用程序。一般來說,所有的狀態改變都應該通過redux來處理,但是對於那些似乎不起作用的輸入。所以我有一個管理的輸入組件,這裏是它的構造函數:更新通過道具管理自己國家的組件

constructor(props) { 
    super(props); 

    // Bind functions now 
    this.changeSlider = this.changeSlider.bind(this); 
    this.changeFromInput = this.changeFromInput.bind(this); 
    this.getValue = this.getValue.bind(this); 

    this.state = { 
     min: props.min, 
    } 
} 

一旦組件已經安裝,它管理的是自己的狀態,因爲這樣的:

changeSlider(e) { // input's onClick is binded to this function 
    let val = parseInt(e.target.value,10); 
    this.setState(_.merge({}, this.state, { min: val })); 
    // update redux state 
    _.debounce(this.props.onChange, 50)(val); 
} 

因此,組件管理它自己的狀態並通過onChange支柱告訴其他應用程序。

這個道具是基於路由安裝:

<Router history={browserHistory}> 
    <Route path="/" component={App}> 
     <IndexRedirect to="/Path/1" />  
     <Route path="Path" component={Container}> 
      <Route path="1" component={Component} /> 
      <IndexRedirect to="1" /> 
     </Route> 
    </Route> 
</Router>  

Container負責從查詢字符串抓取狀態:

// in Container 
componentWillMount() { 
    let {min} = this.props.location.query; 
    this.props.actions.changeMin(min); 
} 

Container再差一些道具到它的孩子,並呈現他們。

如果我訪問/Path/1?min=123123,組件被掛載,那麼在componentWillMount()中會觸發redux dispatch事件。發送到組件的道具將被更新,但它們將被忽略。它們僅用於在構造函數中設置組件狀態。

編輯:選定的答案是正確的。在發佈這個問題之前,我曾嘗試過,但反彈功能導致了一些奇怪的行爲。

+0

這是不是真的清楚你的問題是什麼 – patrick

回答

0

如果我理解正確,您正在更新道具傳遞到組件更新時的狀態。

這最好在componentWillReceiveProps生命週期方法中完成。

constructor(props) { 
    super(props); 

    // Bind functions now 
    this.changeSlider = this.changeSlider.bind(this); 
    this.changeFromInput = this.changeFromInput.bind(this); 
    this.getValue = this.getValue.bind(this); 

    this.state = { 
     min: props.min, 
    } 
} 

// Add this method 
componentWillReceiveProps(nextProps) { 
    this.setState({ 
     min: nextProps.min, 
    }) 
} 

文檔:https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops

+0

我曾嘗試這樣做,也沒有工作,但我發現這個問題。一位同事補充說,「_.debounce」可能會降低行動噪音。這延遲了信息的執行並造成了一些奇怪的競爭條件。 – Dave