React JS setState ({dict: dict})

I wonder if this is the correct solution for updating state with two dictionaries

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

      

if anyone knows of a better and faster solution ask for a hint ...

+3


source to share


2 answers


It is much safer and more efficient to use your state as a simple object with primitive values:

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

      

If you really need to store your values ​​in a nested object, you need to remember to clone the nested object before modifying it:



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

      

I've made your initial state a little smaller to keep your code examples simpler.

Also consider using React Immetwability Helpers , which makes working on nested objects within the state more secure.

+1


source


I forgot to add that the arguments to the handleM function are sent by the child. In my solution it doesn't work accurately (the slider that adjusts the prod_diff attenuation), the same effect occurs when I apply @ daniula's solution Now I decided to use CortexJS and everything works smoothly I would ask me to fix if I misused this library:

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>
        )
    }
})

      

SLIDER

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

      

0


source







All Articles