Javascript 推送到useReducer的特定路径处的数组';s州
我有一个名为Javascript 推送到useReducer的特定路径处的数组';s州,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我有一个名为Form的(功能性)组件,在其中我使用useReducer()hook设置一个如下所示的状态: { content: { profile: { firstName: 'John', lastName: 'Doe' }, experiences: [ { employer: 'CompanyX', position: 'CEO' }, { employ
Form
的(功能性)组件,在其中我使用useReducer()
hook设置一个如下所示的状态:
{
content: {
profile: {
firstName: 'John',
lastName: 'Doe'
},
experiences: [
{
employer: 'CompanyX',
position: 'CEO'
},
{
employer: 'CompanyY',
position: 'Intern'
}
]
}
};
case 'ADD_EXPERIENCE': {
return {
...state,
content: {
...state.content,
experiences: [...state.content.experiences, action.newExperience]
}
}
}
我想把一个新的经验推到经验数组中,我正在寻找编写我的减速机案例的最佳方法。以下是我提出的解决方案:
// reducer.js
case 'ADD_EXPERIENCE': {
newState = _.clone(state);
newState.content.experiences = _.concat(state.content.experiences, action.newExperience);
return newState;
}
然而,这在我看来并不优雅。我想知道你们有没有更好的解决办法。例如,lodash的setWith()
方法是否合适
// reducer.js
case 'ADD_EXPERIENCE': {
return _.setWith(
_.clone(state),
'content.experiences',
action.newExperience,
() => ???
)
}
您可以使用ES6 spread操作符
…
来分解状态和新体验数组并返回新状态,如下所示:
{
content: {
profile: {
firstName: 'John',
lastName: 'Doe'
},
experiences: [
{
employer: 'CompanyX',
position: 'CEO'
},
{
employer: 'CompanyY',
position: 'Intern'
}
]
}
};
case 'ADD_EXPERIENCE': {
return {
...state,
content: {
...state.content,
experiences: [...state.content.experiences, action.newExperience]
}
}
}
您可以使用ES6 spread操作符
…
来分解状态和新体验数组并返回新状态,如下所示:
{
content: {
profile: {
firstName: 'John',
lastName: 'Doe'
},
experiences: [
{
employer: 'CompanyX',
position: 'CEO'
},
{
employer: 'CompanyY',
position: 'Intern'
}
]
}
};
case 'ADD_EXPERIENCE': {
return {
...state,
content: {
...state.content,
experiences: [...state.content.experiences, action.newExperience]
}
}
}
最后:
case 'ADD_EXPERIENCE':
return _.updateWith(
_.clone(state),
'content.experiences',
(value) => [...value, action.newExperience],
_.clone
);
最后:
case 'ADD_EXPERIENCE':
return _.updateWith(
_.clone(state),
'content.experiences',
(value) => [...value, action.newExperience],
_.clone
);
是的,我想过这个。然而,如果state对象变得更深,我的意思是如果它有更多的嵌套,这个解决方案可能会变得单调乏味。此外,它将强制所有组件重新渲染,即使它们侦听的值没有发生变化(如content.profile),也不应将对象与对象、数组与数组进行比较,因为这种比较比较的是指针,而不是值,并且在两个连续渲染之间很少相同。我同意嵌套对象部分,在这种情况下,您的第一个解决方案足够优雅,您可以使用spread运算符或ES6的concat方法,而不是lodash@TheoAvoyne此解决方案保留
state.content.profiles
对象的标识,并且不会重新呈现(仅)依赖该对象的任何已记忆组件,和shallow一样。clone
是的,我考虑过这个。然而,如果state对象变得更深,我的意思是如果它有更多的嵌套,这个解决方案可能会变得单调乏味。此外,它将强制所有组件重新渲染,即使它们侦听的值没有发生变化(如content.profile),也不应将对象与对象、数组与数组进行比较,因为这种比较比较的是指针,而不是值,并且在两个连续渲染之间很少相同。我同意嵌套对象部分,在这种情况下,您的第一个解决方案足够优雅,您可以使用spread运算符或ES6的concat方法,而不是lodash@TheoAvoyne此解决方案保留state.content.profiles
对象的标识,并且不会重新呈现(仅)依赖该对象的任何已记忆组件,与浅层相同。克隆