反应状态更新不适用于 setState
React state update not working with setState
好吧,就这么简单
我在一系列问题中有一系列答案。
用户可以选择 select 多个答案。
当答案是 selected 时,文本应更改为 selected,如果未 selected,则文本应更改为未 selected。
这些是我尝试更新状态的步骤
第 1 步使用地图
setTestInfo((state) => {
const allStateQuestions = state.info.questions;
const currentQuestion = allStateQuestions.filter(
(question) => question.id === questionId
)[0];
const allAnswersMap = currentQuestion.answers.map((answer) =>
answer.id === answerId
? (() => {
answer.is_chosen = !answer.is_chosen;
return answer;
})()
: answer
);
currentQuestion.answers = allAnswersMap;
return {
...state,
info: {
...state.info,
questions: allStateQuestions,
},
};
});
第 2 步使用查找
setTestInfo((state) => {
const allStateQuestions = state.info.questions;
const currentQuestion = allStateQuestions.filter(
(question) => question.id === questionId
)[0];
const currentAnswer = currentQuestion.answers.find(
(answer) => answer.id === parseInt(answerId)
);
currentAnswer.is_chosen = !currentAnswer.is_chosen;
// i even went to the extend of reassigning it yet it doesn't work
currentQuestion.answers.filter((answer) => answer.id === answerId)[0] =
currentAnswer;
return {
...state,
info: {
...state.info,
questions: allStateQuestions,
},
};
});
使用上面的示例逻辑后,none 似乎有效
提前致谢
问题
在这两种情况下,您都在改变状态。我将介绍第一个片段。
setTestInfo((state) => {
const allStateQuestions = state.info.questions; // <-- reference to state
const currentQuestion = allStateQuestions.filter( // <-- reference to state
(question) => question.id === questionId
)[0];
const allAnswersMap = currentQuestion.answers.map((answer) =>
answer.id === answerId
? (() => {
answer.is_chosen = !answer.is_chosen; // <-- state mutation!!
return answer;
})()
: answer
);
currentQuestion.answers = allAnswersMap; // <-- state mutation!!
return {
...state,
info: {
...state.info,
questions: allStateQuestions, // <-- saved reference back into state
},
};
});
state.info.questions
状态的 currentQuestion.answers
对象发生了变异,并且 state.info.questions
数组引用从未改变,因此 React 不会将其“视为”更新并且不会触发重新渲染。
解决方案
应用不可变更新模式。您必须将所有更新浅复制到 new 数组和对象引用中。
setTestInfo((state) => {
return {
...state,
info: {
...state.info,
// new questions array
questions: state.info.questions.map(question => question.id === questionId
? { // new question object
...question,
// new answers array
answers: question.answers.map(answer => answer.id === answerId
? { // new answer object
...answer,
is_chosen: !answer.is_chosen,
}
: answer
),
}
: question
),
},
};
});
好吧,就这么简单
我在一系列问题中有一系列答案。 用户可以选择 select 多个答案。
当答案是 selected 时,文本应更改为 selected,如果未 selected,则文本应更改为未 selected。
这些是我尝试更新状态的步骤
第 1 步使用地图
setTestInfo((state) => {
const allStateQuestions = state.info.questions;
const currentQuestion = allStateQuestions.filter(
(question) => question.id === questionId
)[0];
const allAnswersMap = currentQuestion.answers.map((answer) =>
answer.id === answerId
? (() => {
answer.is_chosen = !answer.is_chosen;
return answer;
})()
: answer
);
currentQuestion.answers = allAnswersMap;
return {
...state,
info: {
...state.info,
questions: allStateQuestions,
},
};
});
第 2 步使用查找
setTestInfo((state) => {
const allStateQuestions = state.info.questions;
const currentQuestion = allStateQuestions.filter(
(question) => question.id === questionId
)[0];
const currentAnswer = currentQuestion.answers.find(
(answer) => answer.id === parseInt(answerId)
);
currentAnswer.is_chosen = !currentAnswer.is_chosen;
// i even went to the extend of reassigning it yet it doesn't work
currentQuestion.answers.filter((answer) => answer.id === answerId)[0] =
currentAnswer;
return {
...state,
info: {
...state.info,
questions: allStateQuestions,
},
};
});
使用上面的示例逻辑后,none 似乎有效 提前致谢
问题
在这两种情况下,您都在改变状态。我将介绍第一个片段。
setTestInfo((state) => {
const allStateQuestions = state.info.questions; // <-- reference to state
const currentQuestion = allStateQuestions.filter( // <-- reference to state
(question) => question.id === questionId
)[0];
const allAnswersMap = currentQuestion.answers.map((answer) =>
answer.id === answerId
? (() => {
answer.is_chosen = !answer.is_chosen; // <-- state mutation!!
return answer;
})()
: answer
);
currentQuestion.answers = allAnswersMap; // <-- state mutation!!
return {
...state,
info: {
...state.info,
questions: allStateQuestions, // <-- saved reference back into state
},
};
});
state.info.questions
状态的 currentQuestion.answers
对象发生了变异,并且 state.info.questions
数组引用从未改变,因此 React 不会将其“视为”更新并且不会触发重新渲染。
解决方案
应用不可变更新模式。您必须将所有更新浅复制到 new 数组和对象引用中。
setTestInfo((state) => {
return {
...state,
info: {
...state.info,
// new questions array
questions: state.info.questions.map(question => question.id === questionId
? { // new question object
...question,
// new answers array
answers: question.answers.map(answer => answer.id === answerId
? { // new answer object
...answer,
is_chosen: !answer.is_chosen,
}
: answer
),
}
: question
),
},
};
});