ReactJS:如何使用动态键访问和更新嵌套状态对象?

hu7*_*7sy 1 javascript ecmascript-6 reactjs

假设我有一个状态定义如下的组件:

this.state = {
    apple:{
        a:1,
        b:2,
    },
    mango:{
        banana : {
            a:1,
            b:2,
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我想更新我的状态中嵌套对象的值,我可以使用硬编码键来执行此操作,如下所示:

cost temp =  { ...this.state['mango'] }
temp['banana']['a'] = 2;

this.setState({mango:temp});
Run Code Online (Sandbox Code Playgroud)

如何动态更新状态对象中的嵌套值键?例如,如果我有一个点或数组表示法的 JSON 路径,我如何更新我的组件状态?

Dac*_*nny 5

实现此目的的一种方法是获取嵌套对象,该对象是路径所针对的字段的父级Array#reduce

const nestedObject = path
.slice(0, -1)
.reduce((object, part) => (object === undefined ? undefined : object[part]), { ...state })
Run Code Online (Sandbox Code Playgroud)

然后nestedObject通过路径的最后一个键更新 by 的最后一个键/值:

/* Get last part of path, and update nestedObject's value for this key, to 2 */
const [pathTail] = path.slice(-1);    
nestedObject[pathTail] = 2;
Run Code Online (Sandbox Code Playgroud)

下面的代码片段同时展示了这两个想法:

const nestedObject = path
.slice(0, -1)
.reduce((object, part) => (object === undefined ? undefined : object[part]), { ...state })
Run Code Online (Sandbox Code Playgroud)

更新

以下是一些额外的细节,概述了reduce()答案部分的工作原理:

path
/* slice obtains ['mango', 'banana'], seeing -1 clips last item */
.slice(0, -1)  
/* reduce iterates through each part of array ['mango', 'banana']
where at each iteration we fetch the corresponding nested object 
of the { ...state } object that's passed in */
.reduce((object, part) => {

/* At iteration 1: 
object has two keys, 'apple' and 'mango'
part is 'mango'
object is defined, so return object['mango'] for first iteration

At iteration 2:
object passed from last iteration has one key, 'banana'
part is 'banana'
object is defined, so return object['banana'] for second iteration

Reduce complete:
we return object['banana'], which is the same as state['mango']['banana']
*/

if(object === undefined) { return undefined; }

return object[part]

}, stateClone)
Run Code Online (Sandbox Code Playgroud)