2015-01-05 63 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 */ 
    ); 
    } 
});