我使用选择器(不必)检索nextStep
我调度了一些操作,这可以更改我想做的nextStep
,但是nextStep
不会被以下代码更新。
const App = (props) => {
const dispatch = useDispatch()
const nextStep = useSelector(getNextStep)
const handleSubmit = () => {
dispatch(someAction()) // this can change the nextStep
dispatch(gotoStep(nextStep)) // this nextStep is computed before someAction
}
}
export const getNextStep = (state) => {
let {step, stepList} = state.my_reduxer
let index = stepList.indexOf(step) // someAction changes stepList
let next_step = stepList[index + 1]
return next_step
}
如何获取nextStep
操作的更新后的gotoStep
?
-编辑
我可以想到以下内容,但不确定是否可以保证正确的行为
const App = (props) => {
const dispatch = useDispatch();
const nextStep = useSelector(getNextStep);
const [done, setDone] = useState(false);
const handleSubmit = () => {
dispatch(someAction()); // this can change the nextStep
setDone(true);
};
useEffect(() => {
if (done) {
dipatch(gotoStep(nextStep)); // nextStep is hopefully updated?
}
}, [done]);
};
答案 0 :(得分:1)
someAction
可能会更改nextStep
,也可能不会更改nextStep,我想在完成更新并可能更新nextStep
后前进到nextStep
。
此代码保证仅当done
发生变化且没有固定价值时才推进下一步。
const App = () => {
const nextStep = useSelector(getNextStep);
const stepRef = useRef(nextStep);
const handleSubmit = () => {
dispatch(someAction());
setDone(true);
};
useEffect(() => {
if (done) {
dispatch(gotoStep(stepRef.current));
}
}, [done]);
useEffect(() => {
stepRef.current = nextStep;
}, [nextStep]);
};
答案 1 :(得分:0)
假设触发效果的是nextStep
本身,因为如果您使用done
状态,仍然不能保证对象已经减少
useEffect(() => dipatch(gotoStep(nextStep)), [nextStep]);
如果在初始化渲染时您不希望这种效果运行,请使用以下命令
const [ isInit, setIsInit ] = useState(true)
useEffect(() => isInit ? setIsInit(false) : dipatch(gotoStep(nextStep)), [nextStep]);
现在您的handleSubmit
函数仅在分派时起作用
const handleSubmit = () => dispatch(someAction()); // this can change the nextStep
答案 2 :(得分:0)
感谢@Dennis Vash的讨论!
我不确定您的解决方案是否可以解决我在评论中提出的问题
这是我的解决方案,我仍然没有确定的书面答案,但使用起来更安全。 (而且似乎可行)
const App = (props) => {
const dispatch = useDispatch();
const nextStep = useSelector(getNextStep);
const myStepDone = useSelector(getMyStep);
const handleSubmit = () => {
dispatch(someAction()); // this can change the nextStep
dispatch(updateMyStepDone()); // let's use redux state for done
};
useEffect(() => {
if (myStepDone) {
dipatch(gotoStep(nextStep)); // I hope actions I submitted in handleSubmit updates state simulateneously
}
}, [myStepDone]);
};