【问题标题】:Wait for action to update state in react-native and redux等待操作以更新 react-native 和 redux 中的状态
【发布时间】:2017-01-31 19:03:48
【问题描述】:

我有一个简单的 react-native 应用程序,并设置了 redux 商店。基本上我想添加一个新故事,调度 redux 动作并在它创建后过渡到这个新故事。

我的容器组件中有以下代码,它在用户点击add 按钮时运行。

 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?分派不应该是同步的吗?

【问题讨论】:

  • 你不能使用.then(() => Actions.editor如果createStory()没有返回一个promise,如果你不想使用promise,你可以使用回调,但是在这种情况下,promise 更好。
  • 当你返回一个承诺时,.then 只会在它解决后被调用。如果您想在出现错误时执行其他操作,请使用 .catch
  • 嗯,是的。但问题是在这里使用 Promise 感觉很奇怪。假设我不使用承诺并且让动作创建者只返回动作。如果我调用 createStory() 然后调用转换 Action.editor({ // ... }) 应用程序将转换到倒数第二个故事,因为状态尚未更新。
  • 没错,所以你等待状态更新然后你转换。,所以它会有最新的 id,无论如何你可以很容易地如果可能获取/设置`addStory()` 中的 id,然后使用该 id 进行转换,您也可以使用 setTimeout - 我不推荐它,无论如何使用 Promise 很好,因为如果以后您想将数据保存在数据库中在更新您的状态之前,您可以这样做而不更改转换代码,但如果不是这种情况,那么您可以使用 callbacks

标签: javascript react-native redux


【解决方案1】:

如 cmets 中所述

回调示例:

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。
  • 动作必须是普通对象。使用自定义中间件进行异步操作。
  • 对我来说,回调实现不起作用,但 Promise 确实起作用。
猜你喜欢
  • 2018-04-19
  • 2022-08-17
  • 1970-01-01
  • 1970-01-01
  • 2019-03-16
  • 2020-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多