你如何从 react-redux 存储中取回数据?

How do you get data back from a react-redux store?

使用 React-Redux

我有一个 select 列表,当用户选择其中一个选项时,将创建一个项目并将其放入数据库(如果重要的话,它的 select 框的原因是同一件商品有多个变体,哪个变体很重要)。

这工作正常。

我的问题是我不确定如何从 redux 商店中获取新项目的 ID。

只是为了笑,之前的开发人员用 sagas 设置了所有这一切。所以我仍在快速了解它们是如何协同工作的。

所以当 select 框被选中时,函数 checkFunction 被调用,调用 saga 文件中的函数 createItem。这些功能如下:

在Repositories.jsx

  checkFunction = (data) => {
    const {createItem} = this.props;
    // data holds the info that we need to send to the action
    const created = createItem(data);
    // once data comes back, redirect the user ot the details of the created item
    // need id of created item
    // navigateTo(`/item-details/${created.id}`);
  }

在Repositories.saga.js

export function* createItem(action) {
  try {
    const {payload: newItem} = action;
    // call api to create item
    const created = yield call(requestAPI.post, ITEMS_URL, newItem);
    // send message that its been done
    yield put(actions.repositories.createItem.ok(created));
    // send message to refresh item list
    yield put(actions.inventories.fetchItems.start());
  } catch (e) {
    yield put(actions.repositories.createItem.fail(e));
  }
}

我不明白如何 return 创建项目后的 ID。我觉得我在这里缺少一些基本的东西。谁能指出我正确的方向?

实际上,从 saga 获取数据返回到 React 组件并不简单。有多种方法可以满足您的需求,尽管每种方法都有其缺点。

1.在 saga 中调用 navigateTo

export function* createItem(action) {
    ...
    const created = yield call(requestAPI.post, ITEMS_URL, newItem);
    yield call(navigateTo, `/item-details/${created.id}`)
}

如果您可以将 navigateTo 函数添加到 saga 中,这将是我推荐的解决方案。导航是一种副作用,而 sagas 就是用来处理副作用的。确保使用 call 效果,通过直接调用函数更改 url 可能会导致一些问题。

2。将最新创建的项目 id 存储在 redux store

在你的 reducer 中,当 action actions.repositories.createItem.ok(created) 被分派时,存储创建的项目信息,然后将最新创建的项目发送到组件。最后你可以使用 componentDidUpdateuseEffect 在 prop 变化时调用 navigateTo

render() {
    const created = Redux.useSelector(state => state.created);
    useEffect(() => navigateTo(`/item-details/${created.id}`), [created])
    ...
}

这有一个缺点,即组件将由于更改的 created 值而重新呈现。

3。在 createItem 操作中发送回调

您可以将一个函数放入您的操作中,然后从 saga 中调用它并将其用作回调。

组件:

checkFunction = (data) => {
    const {createItem} = this.props;
    // data holds the info that we need to send to the action
    const created = createItem(data, (created) => {
        navigateTo(`/item-details/${created.id}`);
    });
}

传奇:

export function* createItem(action) {
    ...
    const created = yield call(requestAPI.post, ITEMS_URL, newItem);
    action.callback(created)
    ...
}

这种方法的问题是函数不可序列化,因此您最好在操作中避免使用它们。此外,从技术上讲,可能有多个 sagas 处理相同的操作,然后会让人有点困惑应该由谁来调用回调。