如何等待 Redux 操作从 React 组件更改状态

ade*_*rey 5 javascript async-await reactjs redux

我在一个组件中,它有一个currentLineIndex由其父容器传递并来自 Redux 减速器的 prop 。

在同一个组件的函数中,我currentLineIndex使用动作创建者进行更新,然后我想滚动到新的currentLineIndex. 但它还没有更新,所以我滚动到同一行。

我试过使用async/await如你所见,但它不起作用。

在我的组件中:

const { currentLineIndex, setCurrentLineIndex } = props; // passed by the parent container 

const handlePlaybackEnd = async () => {
  const nextIndex = currentLineIndex + 1;
  // await don't wait until global state / component props gets updated
  await setCurrentLineIndex(nextLineIndex);
  // so when I scroll on next line, I scroll to the same line.
  scrollToCurrentLine(); 
};

const scrollToCurrentLine = () => {
  const currentLineEl = document.getElementById(currentLineIndex);
  currentLineEl.scrollIntoView({ block: 'start', behaviour: 'smooth' });
};
Run Code Online (Sandbox Code Playgroud)

actions/index.js

export function setCurrentLineIndex(index) {
  return { type: SET_CURRENT_LINE_INDEX, payload: index };
}
Run Code Online (Sandbox Code Playgroud)

在我的减速器中:

case SET_CURRENT_LINE_INDEX:
  return {
    ...state,
    currentLineIndex: action.payload,
  };
Run Code Online (Sandbox Code Playgroud)

Action 和 reducer 运行良好,我的组件状态已成功更新,但为时已晚。

我真的需要依赖 Redux 状态,而不仅仅是传递currentLineIndexto scrollToCurrentLine(),那太容易了:)

等待组件状态更新的最佳解决方案是什么?

ade*_*rey 1

我最终通过使我的组件成为类组件来解决这个问题,这样我就可以使用componentDidUpdate

componentDidUpdate(prevProps) {
  if (prevProps.currentLineIndex !== this.props.currentLineIndex) {
    this.scrollToCurrentLine(this.props.currentLineIndex);
  }
}

handlePlaybackEnd = () => this.props.setCurrentLineIndex(this.props.currentLineIndex + 1);
Run Code Online (Sandbox Code Playgroud)

2020 更新

Hooks 让它变得更简单,不需要类组件,只需使用效果:

const scrollToCurrentLine = useCallback(() => {
  const currentLineEl = document.getElementById(currentLineIndex);
  currentLineEl.scrollIntoView({ block: 'start', behaviour: 'smooth' });
}, [currentLineIndex]);

useEffect(scrollToCurrentLine, [scrollToCurrentLine]);
Run Code Online (Sandbox Code Playgroud)