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