React Context状态被自动擦除,无法更新单个字段



我有一个简单的reducer/context系统来存储状态。一切都很好,只是我不能单独更新字段而不影响其他字段的状态。

问题是,当我更改其中一个AppData字段时,其他字段变为空白。我不知道我做错了什么,我希望能够更新单个值,同时保留其他字段的值。

例如:如果我只更新appData.headerTitle值,那么appData.testValueappData.userHasLoggedOut值将被擦除。如果我同时更新这3个值,那么什么都不会被删除。我希望能够只更新一个字段,而不删除其余的。

export function AppReducer(state: AppState, action: Actions): AppState {
switch (action.type) {
case 'setAppData':
return {
...state,
appData: action.payload
};
case 'changeAppData':
return {
...state,
appData: {
...state.appData,
headerTitle: action.payload,
testValue: action.payload,
userHasLoggedOut: action.payload
}
};
}
}

带有完整工作代码的沙盒:https://codesandbox.io/s/frosty-cache-c6yqgx?file=/src/middlewares/reducer/AppReducer.tsx

谢谢!

我不知道该在这里尝试什么。。。

每次进行更改时,都会发送一个有效载荷,该有效载荷是一个具有ONE属性的对象,例如在App.tsx第22行中,它是一个带有一个属性headerTitle的对象。

所以AppReducer.tsx第9行中的这个对象覆盖了整个当前状态,所以如果有任何其他属性,它们将被覆盖并消失。

为了解决这个问题,我建议你分散这个有效载荷,用数据保存以前的字段:

case "setAppData":
return {
...state,
appData: {
...state.appData,
...action.payload
}
};

提示:实际上,我不知道为什么在这种状态下有一个appData字段。如果房产直接在州内,也许会更容易、更干净。我的意思是,而不是这种结构

export type AppState = {
appData: {
headerTitle?: string;
testValue?: string;
userHasLoggedOut?: boolean;
};
};

使用类似的东西:

export type AppState = {
headerTitle?: string;
testValue?: string;
userHasLoggedOut?: boolean;
};

您的changeAppData案例出现了一些问题。另外,感觉代码中缺少了一些部分,例如,在useContext钩子中没有返回changeAppDatafn。但据我所见,当您遇到changeAppData情况时,所有三个appData值都将是相同的,因为它们都设置为action.payload

你可以(我也愿意(在这里打断你的changeAppData行动。我在看你的代码沙盒,你实际上并没有同时更新多个值。你正在单独更新状态,所以你还不如有更多的描述性操作。。除此之外,您实际上并不需要在状态中嵌套这个额外的appData对象层。所以可能低于

switch (action.type) {
case 'SET_HEADER_TITLE':
return {
...state,
headerTitle: action.payload,
};
case 'SET_USER_LOGGED_OUT':
return {
...state,
userHasLoggedOut: action.payload
};
default: // Don't forget your default case
break;
}

如果您坚持要将它们嵌套在另一个对象下,在本例中为appData。您需要从reducer中获取状态对象,然后将该对象与update键/属性一起传入。

switch (action.type) {
case 'setAppData':
return {
...state,
appData: action.payload
};
case 'UPDATE_APP_DATA':
return {
...state,
appData: action.payload
};
default: // Don't forget your default case
break;
}

然后类似于:

changeAppData({
...state,
testValue: 'Updated Test Value Here'
})

编辑:我刚刚意识到我做的UPDATE_APP_DATA箱子和你的setAppData完全一样。。哈哈,好吧,你只需要第一个病例。然而,我可能不会这样做,因为每次都需要传入整个对象。

相关内容

  • 没有找到相关文章

最新更新