我可以根据其他状态变量更新状态吗(如下setCurrentQuestion()
所示(,还是会导致意外问题?
我能想出两个解决办法:
- "外部";调用传递到
getQuestionByIndex()
选择器的getCurrentQuestionIndex()
选择器的helper函数,该选择器返回我传递给setCurrentQuestion()
reducer的IQuestion
对象 - 保持原样,但使用草稿安全选择器,而不是直接访问状态对象
const slice = createSlice({
name: 'blabla',
initialState: { questions: undefined, currentQuestion: undefined, noOfQuestions: 0, currentQuestionIndex: 0 } as QuizState,
reducers: {
setQuestions: (state, action: PayloadAction<IQuestion[]>) => {
state.questions = action.payload;
},
setCurrentQuestion: (state, action: PayloadAction<number>) => {
if (!state.questions) return
state.currentQuestion = state.questions[state.currentQuestionIndex]
}
},
state.currentQuestion
不应该存在于您的状态中。你得到了state.questions
作为真理的来源,state.currentQuestionIndex
来记住哪个问题是当前的问题。任何进一步的东西都不再是原子和最小的了。有一个state.currentQuestion
复制state.questions
中的一个项目当然是可行的,但最终会出现类似这样的问题。我建议添加一个选择器getCurrentQuestion()
,它可以进行查找,并且可以处理state.questions
的错误。它也永远不应该是数组btw,如果类型不变,处理状态会更容易。我会将其初始化为一个空数组,然后选择器可以是:
const getCurrentQuestion = (state) => state.questions[state.currentQuestionIndex];
为了解决您的想法,在reducer中对状态进行更改之前,先查看状态的不同部分,您还可以使用thunk-它们在作用域中有getState()
,并且可以运行条件逻辑。因此,如果state.questions
是错误的,您可以简单地不发送setCurrentQuestion
。但是imo的一个更好的解决方案是我上面描述的选择器。