2015-01-05 101 views
3

我不知道這是否是正確的解決方案,以更新狀態有兩個dictionares陣營JS的setState({字典:字典})

var PopulationCityView = React.createClass({ 
    getInitialState: function() { 
     return { 
      prod_diff : {'wheat':0,'meat':0,'fish':0,'bread':0,'fruit':0,'wine':0,'beer':0,'wool':0,'cloth':0,'leather':0,'paper':0,'ceramics':0,'furniture':0,'glass':0} 
      }; 
    }, 
    componentWillMount: function() { 
     this.prod_diff = {'wheat':0,'meat':0,'fish':0,'bread':0,'fruit':0,'wine':0,'beer':0,'wool':0,'cloth':0,'leather':0,'paper':0,'ceramics':0,'furniture':0,'glass':0}; 
    }, 
    handleM: function(res,child_new_res_diff){ 
     var new_prod_diff = this.prod_diff; 
     new_prod_diff[res] = child_new_res_diff; 
     this.setState({prod_diff:new_prod_diff}); 
    }, 
    render: function(){ 
........ 

,如果任何人更好,更快的解決方案都知道會要求一個提示。 ..

回答

1

更安全和更有效的方式是保持狀態的簡單對象與原始值:

var PopulationCityView = React.createClass({ 
    getInitialState: function() { 
     return { 
      wheat: 0, 
      meat: 0, 
      fish: 0, 
     }; 
    }, 
    handleM: function(res,child_new_res_diff){ 
     var new_state = {}; 
     new_state[res] = child_new_res_diff; 
     this.setState(new_state); 
    }, 
    render: function() { /* your render code */ } 
}); 

如果你真的有你的值存儲在嵌套的對象,你必須記住要克隆在修改它之前嵌套對象:

var PopulationCityView = React.createClass({ 
    getInitialState: function() { 
     return { 
      prod_diff: { wheat: 0, meat: 0, fish: 0 } 
     }; 
    }, 
    handleM: function(res,child_new_res_diff){ 
     var new_prod_diff = _.clone(this.state.prod_diff); 
     new_prod_diff[res] = child_new_res_diff; 
     this.setState({ prod_diff: new_prod_diff }); 
    }, 
    render: function() { /* your render code */ } 
}); 

我已經使您的初始狀態稍微小一點以簡化代碼示例。

還要考慮使用這使得裏面的狀態更安全嵌套對象操作React Immutability Helpers

+2

不要直接修改'this.state'。您可以輕鬆地將嵌套對象傳遞給'setState',而不必擔心通過調用'forceUpdate'來攻擊API。 – couchand

+0

@couchand這就是爲什麼我建議第一個解決方案更好,但總是有一些邊緣案例。然而,你是正確的forceUpdate是危險的,所以我糾正了我的第二個解決方案。 – daniula

0

我忘了添加handleM函數參數是由孩子發送的。 在我的解決方案並不順利工作(即調整prod_diff果醬滑塊),同樣的效果是當我申請@daniula 現在我已經決定利用CortexJS和一切順利 我想請大家指正解決方案如果我用這個庫錯誤:

家長

var PopulationCityView = React.createClass({ 
    getInitialState: function() { 
     return { 
      prod_diff_C : new Cortex({'wheat':0,'meat':0,'fish':0,'bread':0,'fruit':0,'wine':0,'beer':0,'wool':0,'cloth':0,'leather':0,'paper':0,'ceramics':0,'furniture':0,'glass':0}), 
      }; 
    }, 
    componentWillUnmount: function() { 
     delete this.state.prod_diff_C; 
    }, 
    componentDidMount: function(){ 
     var that = this; 
     this.state.prod_diff_C.on("update",function (updatedRes) {that.setState({prod_diff_C: updatedRes});}); 
    }, 
    // handleM: function(res,child_new_res_diff){ 
     // var new_prod_diff = this.prod_diff; 
     // new_prod_diff[res] = -child_new_res_diff; 
     // this.setState(new_prod_diff); 
    // }, 
    render: function(){ 
     var foods = {}, goods = {}; 
     for(var g = 0; g< this.goods.length; g++){ 
      R = this.goods[g]; 
      goods[R] = <div style={{display:"inline-block"}}> 
        <CHILD_1 res_par={this.props.data.res_uses[R]} res={R} prod_diff_cortex={this.state.prod_diff_C}/> 
        <SLIDER prod_diff_cortex={this.state.prod_diff_C} res={R} res_have={this.props.data.res_uses[R][0]} res_need={this.props.data.res_uses[R][1]} /> 
       </div> 
     } 

     } 
     return ( .... ) 
    } 
}) 

CHILD_1

var CHILD_1 = React.createClass({ 
    render: function(){ 
     var val = this.props.res_par[3] + this.props.prod_diff_cortex[this.props.res].getValue() 
     return (
      <div className='population-production-upkeep'>    
       {val} 
      </div> 
     ) 
    } 
}) 

滑塊

var SLIDER= React.createClass({ 
...... 
    handleMouseDown: function(event){ 
    var start_val = this.props.res_have + this.props.prod_diff_cortex[this.props.res].getValue() 
    this.val_start = start_val; 
    this.res_diff_start = this.props.prod_diff_cortex[this.props.res].getValue() 
    this.touched = 1; 
    this.pos_start_x = event.screenX; 
    this.prev_pos_x = this.width_step * start_val; 
    event.stopPropagation(); 
    event.preventDefault(); 
    }, 
    handleMouseMove: function(event){ 
    if(this.touched) { 
     var x_diff = event.screenX - this.pos_start_x ; 
     var x = this.prev_pos_x + x_diff; 
     if (x < 0) x = 0; 
     if (x > this.state.max_pos_x) x = this.state.max_pos_x; 
     var stor = Math.round(x* 100/this.width_step)/100 
     var new_res_diff = this.res_diff_start + stor - this.val_start; 
     this.props.prod_diff_cortex[this.props.res].set(new_res_diff) 
    } 
    }, 
...... 
    render: function() { 
    var val = Math.round((this.props.res_have+this.props.prod_diff_cortex[this.props.res].getValue())*100)/100; 
    return (
       ..../* slider render */ 
    ); 
    } 
});