如何在reactJS的嵌套状态对象中使用reduce函数?

时间:2019-05-10 12:44:51

标签: javascript reactjs ecmascript-6

我的状态值为

this.state = {
    content: {
        text: {
            tag1: {
                line: "data1"
            }
            tag2: {
                line: "data2"
            }
        }
    }
}

如何使用JavaScript reduce()函数将linetag1的{​​{1}}的值都更改为tag2

4 个答案:

答案 0 :(得分:1)

您应该setState使用某个函数,以免直接更改state

this.setState(prevState => {        
    for(let k in prevState.content.text){
        prevState.content.text[k].line = "changed";
    } 
    return {content: prevState.content}
}

编辑:

我不确定直接更改prevState是否是一件好事(请纠正我),但是您也可以

this.setState(prevState => {   
    let changedState = {...prevState}     
    for(let k in changedState.content.text){
        changedState.content.text[k].line = "changed";
    } 
    return {content: changedState.content}
}

编辑:

如评论中所述,{...prevState}将是一个浅表副本,它仍然可以直接更改状态。一种解决方案是使用lodash cloneDeep

答案 1 :(得分:1)

您在这里:

this.setState(prevState => {
    return {
        content: {
            ...prevState.content,
            text: Object.keys(prevState.content.text).reduce((newTexts, key) => {
                return {
                    ...newTexts,
                    [key]: {
                        line: "changed text"
                    }
                }
            }, {})
        }
    }
});

答案 2 :(得分:0)

我认为使用for..in会更好。

const state = {
    content: {
        text: {
            tag1: {
                line: "data1"
            },
            tag2: {
                line: "data2"
            }
        }
    }
}

for(let k in state.content.text){
  state.content.text[k].line = "changed";
} 
console.log(state)

答案 3 :(得分:0)

我认为Array#prototype#reduce不适合。

您可以对Object.entries使用普通的现代for...of循环并执行以下操作:

const state = {
    content: {
        text: {
            tag1: {
                line: "data1"
            },
            tag2: {
                line: "data2"
            }
        }
    }
};

for (const obj of Object.entries(state.content.text)) {
	obj[1].line = 'Changed text';
}

console.log(state);


要获得不可变状态,可以在使新对象的属性发生突变之前执行Object.assign

const state = {
  content: {
    text: {
      tag1: {
        line: "data1"
      },
      tag2: {
        line: "data2"
      }
    }
  }
};

// Create a new object from an existing object
const newState = Object.assign(state, {});

Object.entries(newState.content.text).forEach(x => {
  x[1].line = 'Changed text';
});

console.log(newState);