由於需要對state中定義的對象屬性做變更操作,卻發現setState是不能直接對state中的對象屬性進行操作的。
那我們應該怎么辦呢?不要捉急,聽我慢慢道來(😜壓根不想聽你廢話……)
首先,我們在state中定義一個對象:
this.state = {
obj: {}
}
下一步操作是給obj這個對象動態的增加name,age兩個屬性並初始化賦值,根據setState的特性,是可以直接更改obj屬性,所以我們可以新建一個object對象,取名為coverObj,然后給coverObj添加name,age屬性和初始值,這個時候我們得到的obj對象就和coverObj是一樣的啦!如下:
let coverObj = {};
coverObj['name'] = '小明',
coverObj['age'] = 20,
this.setState({
obj: coverObj
})
按照上面的方式的話,其實就是將coverObj直接覆蓋給obj,如果obj本身就存在其他屬性,那么就會導致其他屬性的丟失。
this.state = {
obj: {hobby: '游泳'}
}
let coverObj = {};
coverObj['name'] = '小明',
coverObj['age'] = 20,
this.setState({
obj: coverObj
})
// 打印出來的obj是沒有hobby屬性的
因此,我們就需要用到Object.assign()方法來更改整個對象:
let coverObj = {};
coverObj['name'] = '小明',
coverObj['age'] = 20,
let data2 = Object.assign(this.state.obj, coverObj) // 1
// let data2 = Object.assign({},this.state.obj, coverObj) // 2
this.setState({
obj: data2
})
注釋1、2:以上兩種方式的返回值是一樣的。由於Object.assign的語法是將第一個參數當做目標對象,在目標對象的基礎上進行操作的,也就是說會改變原來的目標對象,所以一般在使用Object.assign的時候會將目標設置為空對象,相當於返回一個全新的對象。
接下來,我們把屬性name的值變更為『小紅』,前提是obj中已經存在了需要做更改的屬性,且屬性名與變更值的屬性名一致,更改對象中的某個屬性:
let coverObj = {};
coverObj['name'] = '小明',
coverObj['age'] = 20,
let data2 = Object.assign({},this.state.obj,coverObj, {name: '小紅'}) ;
this.setState({
obj: data2
})
// 打印的 obj: {hobby: '游泳', name: '小紅', age: 20}
這個時候就達到了我們想要更改對象屬性值的目的了。
Object.assign相關:
Object.assign() 方法用於將所有可枚舉屬性的值從一個或多個源對象分配到目標對象。它將返回目標對象。
語法:Object.assign(target, ...sources)
參考文獻: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
關於 setState() 你應該了解三件事:
1、不要直接修改 State,而是應該使用 setState():
2、State 的更新可能是異步的
3、State 的更新會被合並