[英]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.