2015-01-05 3 views
3

Интересно, если это правильное решение для обновления состояния с двумя dictionaresРеагировать JS SetState ({ДИКТ: 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(){ 
........ 

если кто-нибудь знает лучше и быстрее решения будет просить подсказку. ..

ответ

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', и не должны беспокоиться о взломе API с вызовом' forceUpdate'. – 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> 
     ) 
    } 
}) 

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 */ 
    ); 
    } 
}); 
Смежные вопросы