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

时间:2017-11-06 19:24:34

标签: javascript reactjs redux async-await

我在一个组件中,它有一个道具currentLineIndex通过它的父容器并来自Redux减速器。

在相同组件的功能中,我使用动作创建器更新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,
  };

动作和减速器运行良好,我的组件状态已成功更新,但已经太晚了。

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

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

更新 我通过将我的组件重构为类找到了一种方法,因此我可以使用componentWillReceiveProps(nextProps)然后使用scrollToCurrentLine(nextProps.currentLineIndex)。不确定它是否是最好的方式,但绝对有效。

3 个答案:

答案 0 :(得分:1)

一种解决方案是定义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)

答案 1 :(得分:0)

我终于通过使我的组件成为类组件来解决此问题,因此可以使用componentDidUpdate

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

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

答案 2 :(得分:0)

我通过创建一个小npm模块解决了类似的问题。它允许您订阅和侦听redux动作,并在状态更改完成后立即执行提供的回调函数。用法如下。在您的componentWillMount或componentDidMount挂钩中:

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

详细文档可在this link

中找到