2016-01-22 65 views
21

對於我用我必須有看起來像這樣的狀態的插件:如何爲嵌套數組設置狀態?

getInitialState() { 
    return { 
    invalid: true, 
    access: { 
     access_code: '', 
     zipcode: '', 
     password: '', 
     confirm: '', 
     hospital_id: '', 
    }, 
    } 
}, 

我將如何設置hospital_id的狀態,而無需設置訪問的休息嗎?

這似乎刪除一切,但hospital_id:

this.setState({access: {hospital_id: 1}}) 
+0

我希望做出反應出來有更好的方式來做到這一點,像'updateState()',這將只更新過,而不是颳走了什麼的已經存在的密鑰。我發現所有這些解決方法都是危險的,因爲如果有人忘記將新狀態與現有狀態合併,它會「默默」失敗。 –

回答

52

您可以使用Object.assign或對象傳播建議以創建具有更新屬性的對象的副本。

this.setState({ 
    access: { 
    ...this.state.access, 
    hospital_id: 1, 
    }, 
}); 

this.setState({ 
    access: Object.assign({}, this.state.access, { 
    hospital_id: 1, 
    }), 
}); 

或者最短版本和原子更新:

this.setState(({access}) => ({access: { 
    ...access, 
    hospital_id: 1, 
}}); 

而且多一個選擇是更新的插件:

var update = require('react-addons-update'); 
this.setState({ 
    access: update(this.state.access, { 
    hospital_id: {$set: 1}, 
    }) 
}); 

我會使用第一個。

+3

考慮到React使用最新的ES + Babel(大部分),這應該是被接受的答案。對象擴展運算符是最簡潔易用的。 – ortonomy

+0

真棒.....真的很喜歡ES6的工作方式 –

15

let newAccess = Object.assign({}, this.state.access); 
 
newAccess.hospital_id = 1; 
 
this.setState({access: newAccess});

+9

你不應該直接改變狀態 –

+0

從什麼時候開始?反應文件不建議這樣的規則。 –

+8

[不要直接修改狀態](https://facebook.github.io/react/docs/state-and-lifecycle.html#do-not-modify-state-directly) – lolsheeplol

2

通常情況下,你要爲對象的深拷貝有問題,然後簡單地改變新的屬性。

但是,它沒有這麼多去除一切,但hospital_id,它取代它。設置狀態必須包含完整狀態。

因此,無論您使用的擴展,克隆對象,並更改屬性,或者如果不是這麼多的工作,你可以做這樣的事情:

this.setState({ 
    invalid: state.invalid, 
    access: { 
    access_code: state.access.access_code, 
    zipcode: state.access.zipcode, 
    password: state.access.password, 
    confirm: state.access.confirm, 
    hospital_id: 1, 
    } 
}); 
2

我現在這樣做的首選方法是簡單的:

let newAccess = this.state.access; 
newAccess.hospital_id = 1; 
setState({access: newAccess}); 

略高於目前接受的答案簡單。

編輯(基於問題從@SILENT)

它看起來像這其實是有潛在危險的方法。這裏進一步閱讀React: A (very brief) talk about immutability.

看起來像一個更好的方式來做到這一點是:

let newAccess = Object.assign({}, this.state.access, {hospital_id:1}); 
this.setState({access: newAccess}); 
+1

這不是變異的狀態嗎? – SILENT

+0

看起來你是對的。更新了答案並通過@FakeRainBrigand將接受的答案更改爲了答案 –

1

另一種方式做,這將是

const newAccess = {...this.state.access}; 
newAccess.hospital_id = 1; 
setState({access: newAccess}); 

使用spread operator的產生的this.state.access克隆。