2017-07-13 41 views
1

我正在使用react-select,并且我有两个多选择下拉元素。我宣布我的状态如下:React无法将undefined或null转换为对象

constructor(props){ 

    super(props); 

    this.state = { 
    createNewDeliveryData: { 
      languages: [], 
      markets:[], 

     }, 

    }; 

} 

我有两个函数,添加从我多选择下拉列表中选择语言/市场:

addLanguage = (val) => { 
    // Get a copy of the languages state. 
    const languages = [...this.state.createNewDeliveryData.languages]; 
    for(let i=0; i< val.length; i++){ 
     if(languages.indexOf(val[i].id) === -1) { // notice that there is a parenthesis after `id`. 
      languages.push(val[i].id) 
     } 
    } 
    this.setState(
     { 
      createNewDeliveryData: {languages} 
     }, function() { 
      this.setValue({id:"languages", value:this.state.createNewDeliveryData.languages, error:null}) 
     }); 
} 

addMarket = (value) => { 

    console.log(value) 
    // Get a copy of the markets state. 
    const markets = [...this.state.createNewDeliveryData.markets]; 
    for(let i=0; i< value.length; i++){ 
     if(markets.indexOf(value[i].id) === -1) { // notice that there is a parenthesis after `id`. 
      markets.push(value[i].id) 
     } 
    } 
    this.setState(
     { 
      createNewDeliveryData: {markets} 
     }, function() { 
      this.setValue({id:"markets", value:this.state.createNewDeliveryData.markets, error:null}) 
     }); 
} 

我的选择框:

{/* Language */} 
<Row> 
    <Col xs={3} sm={3} md={2} lg={2}> 
     <div className="test-one"> 
      <FormattedMessage id="language" defaultMessage="Sprache der Lieferung" /> 
     </div> 
    </Col> 
    <Col xs={6} sm={6} md={6} lg={6}> 

     <Select 
      multi={true} 
      name="form-field-name" 
      options={this.props.metadata ? this.props.metadata["latest"].languages : []} 
      labelKey="display_name" 
      valueKey="id" 
      onChange={this.addLanguage} 
      clearable={false} 
      value={this.state.createNewDeliveryData.languages} 
     /> 
    </Col> 
</Row><br/> 

{/* Target market */} 
<Row> 
    <Col xs={3} sm={3} md={2} lg={2}> 
     <div className="test-one"> 
      <FormattedMessage id="market" defaultMessage="Zielmarkt" /> 
     </div> 
    </Col> 
    <Col xs={6} sm={6} md={6} lg={6}> 
     <Select 
      multi={true} 
      name="form-field-name" 
      options={this.props.metadata ? this.props.metadata["latest"].countries : []} 
      labelKey="display_name" 
      valueKey="id" 
      onChange={this.addMarket} 
      clearable={false} 
      value={this.state.createNewDeliveryData.markets} 
     /> 
    </Col> 
</Row><br/> 

我通过拨打后端来填充我的下拉列表。现在的问题是我可以从任何一个框中选择,当我从其他框中选择一个值时,它会引发错误:无法将undefined或null转换为对象。

为什么发生?我究竟做错了什么?

+0

我已经回答了类似的问题昨天。结帐请输入 https://stackoverflow.com/questions/45054970/react-updating-one-state-property-removes-other-states-properties-in-the-state/45055219#45055219 –

回答

2

问题在于您更新状态值的方式。

最初createNewDeliveryData包含两个键:

createNewDeliveryData = { 
    languages: [], 
    markers: [] 
} 

但是当你正在更新的状态要删除的第二个:这个

this.setState({ 
    createNewDeliveryData: {languages} 
    ... 
}) 

含义是:

createNewDeliveryData: {languages: languages} 

现在createNewDeliveryData将只有一种关键语言而不是另一种。

为了解决这个问题,更新状态是这样的:

this.setState({ 
     createNewDeliveryData: {...this.state.createNewDeliveryData , languages:languages } 
    }, function() { 
      this.setValue({id:"languages", value:this.state.createNewDeliveryData.languages, error:null}) 
    }); 
} 

检查这个片段:

//problem 
 

 
let obj1 = {a:1, b:2}; 
 
console.log('initially obj1 = ', obj1); 
 
let b = 4; 
 
obj1 = {b}; 
 

 
console.log('after obj1 = ', obj1); 
 

 
//solution 
 

 
let obj2 = {a:1, b:2}; 
 
console.log('initially obj2 = ', obj2); 
 
b = 4; 
 
obj2 = {...obj2, b}; 
 

 
console.log('after obj2 = ', obj2);

+0

非常感谢这个快速回答!它解决了我的问题。 :) – Nitish

+0

很高兴,它解决了你的问题:) –

相关问题