反应 JS setState({dict : dict })

React JS setState({dict : dict })

我想知道这是否是用两个字典更新状态的正确解决方案

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(){
........

如果有人知道更好更快的解决方案会要求提示...

更安全、更有效的方法是将状态保持为具有原始值的简单对象:

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,这使得对状态内的嵌套对象进行操作更加安全。

我忘了补充一点,handleM 函数参数是由 child 发送的。 在我的解决方案中,它工作不顺利(调整 prod_diff 卡纸的滑块),当我应用解决方案@daniula 时效果相同 现在我决定使用 CortexJS,一切运行顺利 如果我不正确地使用这个库,我会要求纠正我:

PARENT

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