簡體   English   中英

如何等待 Redux 操作從 React 組件更改狀態

[英]How to wait for a Redux action to change state from a React component

我在一個組件中,它有一個由其父容器傳遞並來自 Redux 減速器的道具currentLineIndex

在同一個組件的函數中,我用動作創建者更新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' });
};

actions/index.js

export function setCurrentLineIndex(index) {
  return { type: SET_CURRENT_LINE_INDEX, payload: index };
}

在我的減速器中:

case SET_CURRENT_LINE_INDEX:
  return {
    ...state,
    currentLineIndex: action.payload,
  };

Action 和 reducer 運行良好,我的組件狀態已成功更新,但為時已晚。

我真的需要依賴 Redux 狀態,而不僅僅是將currentLineIndex傳遞給scrollToCurrentLine() ,那太容易了:)

等待組件狀態更新的最佳解決方案是什么?

我最終通過使我的組件成為類組件來解決這個問題,這樣我就可以使用componentDidUpdate

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

handlePlaybackEnd = () => this.props.setCurrentLineIndex(this.props.currentLineIndex + 1);

2020 更新

Hooks 讓它變得簡單了很多,不需要類組件,只需使用一個效果:

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

useEffect(scrollToCurrentLine, [scrollToCurrentLine]);

一種解決方案是定義setCurrentLineIndex以便它接收回調。

//assuming the parent container is a class
setCurrentLineIndex = (index, cb)=>{
    //write the logic here then execute the callback 
    cb()
}

// Then in your child component, you could do something like this 
    setCurrentLineIndex(nextIndex, scrollToCurrentLine)

我通過創建一個小的 npm 模塊解決了類似的問題。 它允許您訂閱和偵聽 redux 操作,並在狀態更改完成后立即執行提供的回調函數。 用法如下。 在您的 componentWillMount 或 componentDidMount 鈎子中:

 subscribeToWatcher(this,[
      {  
        action:"SOME_ACTION",
        callback:()=>{
          console.log("Callback Working");
        },
        onStateChange:true
      },
    ]);

可以在此鏈接中找到詳細的文檔

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM