反应,分派功能组件后获取更新状态

时间:2020-06-05 08:59:41

标签: reactjs redux

我使用选择器(不必)检索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]);
};

3 个答案:

答案 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]);
};