等待动作在react-native和redux中更新状态

4

我有一个简单的React Native应用程序,其中设置了Redux存储。基本上,我想添加一个新故事,分派Redux操作并在创建后转换到这个新故事。

我在容器组件中有以下代码,当用户点击“添加”按钮时运行。

 addStory() {
    this.props.actions.stories.createStory()
      .then(() => Actions.editor({ storyId: last(this.props.stories).id }); // makes the transition)
  }

以下是动作创造者。

export const createStory = () => (dispatch) => {
  dispatch({ type: CREATE_STORY, payload: { storyId: uniqueId('new') } });
  return Promise.resolve();
};

正如您所看到的,我在操作创建器中返回一个Promise。如果我不在这里返回Promise,则转换将在状态更新之前进行。

这对我来说似乎有点奇怪 - 为什么我必须在这里返回已解决的Promise?难道调度程序不应该是同步的吗?


如果**createStory()**函数没有返回一个promise,那么你不能使用.then(() => Actions.editor。如果你不想使用promise,可以使用回调函数,但在这种情况下,promise更好。 - Dhruv Kumar Jha
当你返回一个Promise时,.then将只在它被解决后调用。如果希望在出现错误的情况下执行其他操作,请使用.catch - Dhruv Kumar Jha
是的。但问题在于,在这里使用 Promise 感觉有些奇怪。假设我不使用 Promise,而是让 action creator 直接返回 action。如果我调用 createStory() 然后调用转换 Action.editor({ // ... }),应用程序将转换到倒数第二个故事,因为状态尚未更新。 - Ben Lime
所以,你需要等待状态更新,然后再进行转换。这样它就会有最新的id了。无论如何,你可以在addStory()中轻松地如果可能的话获取/设置id,然后使用该id进行转换,你也可以使用setTimeout - 我不建议这样做。总之,使用Promise很好,因为如果以后你想在更新状态之前将数据保存到数据库中,你可以这样做而不更改转换代码,但如果不是这种情况,那么你可以使用回调函数 - Dhruv Kumar Jha
1个回答

6
在评论中讨论过:
回调函数示例:
addStory() {
    this.props.actions.stories.createStory( (id) => {
        Actions.editor({ storyId: id })
    });
}
export const createStory = ( callback ) => (dispatch) => {
    const _unique_id = uniqueId('new');
    dispatch({ type: CREATE_STORY, payload: { storyId: _unique_id } });
    callback(_unique_id);
};

超时示例: 这里我们假设状态现在已经更新了...但大多数情况并非如此。
addStory() {
    this.props.actions.stories.createStory()
    setTimeout( () => {
        Actions.editor({ storyId: last(this.props.stories).id });
    }, 500);
}
export const createStory = () => (dispatch) => {
    dispatch({ type: CREATE_STORY, payload: { storyId: uniqueId('new') } });
};

承诺:这可能需要一秒钟或一分钟才能完成... 没关系。你在这里做所有必须做的事情,最终解决它,以便应用程序/组件可以执行下一步操作。
export const createStory = () => (dispatch) => {
    return new Promise( (resolve, reject) => {
        // make an api call here to save data in server
        // then, if it was successful do this
        dispatch({ type: CREATE_STORY, payload: { storyId: uniqueId('new') } });
        // then do something else
        // do another thing
        // lets do that thing as well
        // and this takes around a minute, you could and should show a loading indicator while all this is going on
        // and finally
        if ( successful ) {
            resolve(); // we're done so call resolve.
        } else {
            reject(); // failed.
        }
    });
};

现在,请查看http://reactivex.io/rxjs/

谢谢澄清,我在这里做的事情不是错的。我会看一下 RxJS。 - Ben Lime
操作必须是普通对象。对于异步操作,请使用自定义中间件。 - Nishant Ghodke
1
对我来说,回调函数的实现没有起作用,但 Promise 起了作用。 - instanceof

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接