如何在 react/redux 中调用一个 API 并从另一个 child 更新一个 child

How to call an API and update one child from another child in react/redux

我正在使用 redux、react、react-router 和 reselect。有一个包含两个组件的屏幕,HeaderBody。在Header到select中有一个组件的ID。当一个新 ID 被 selected 时,一个新的动作被调度来更新 redux 状态中的 ID。

根据该 ID,应该有一个异步 API 调用来从服务器加载元素并将其存储在状态中,然后应该触发屏幕渲染并在 Body。加载的元素然后会从带有 reselect.

的状态中提取出来

real-life 场景比那更复杂一些,因为有许多不同的 Body 组件具有不同的 API 调用并且只有一个 Header 组件。但它们可以被视为不同的屏幕。所以,例如:

屏幕 1:

组件:HeaderBodyTypeA; API 呼叫:apiA

屏幕 2:

组件:HeaderBodyTypeB; API 呼叫:apiB

我的理解是 API 调用应该在 reducer 将新 ID 存储在状态中时完成。但是,如果操作是由跨屏幕共享的组件分派的,如何确定正在显示哪个屏幕以及调用哪个 API ?我能否以某种方式在 Body 中订阅 ID 的更改并从屏幕内触发 API 调用?屏幕类型由 react-router 决定。减速器是否可以访问路由器以确定正在显示哪个屏幕?有没有处理这种情况的最佳实践?

看来您可能想多了。所以,一次一件事:

My understanding is that the API call should be done in the reducer when it stores the new ID in the state.

除非您将使用允许从 reducer 返回操作的 redux-loop,否则您就错了。原则上,reducer 不能派发任何动作,它们只会消耗它们。它是中间件层(或动作创建者),您可以在其中发送动作并调用 APIs.

But how to determine which screen is being shown and which API to call if the action is dispatched by a component shared across screens?

要确定 "where you are" 最好将路由信息保存在状态树中。由于您无论如何都在使用 React 路由器,请考虑使用 https://github.com/reactjs/react-router-redux 在您的状态树中公开路由信息,然后从您的中间件/动作创建者/选择器访问它。

Can I somehow subscribe in the Body to changes to the ID and trigger the API call from within the screen?

是的,从技术上讲,您可以订阅商店更改,但通常您不会订阅 - 请参阅我的其他观点,希望它足够清楚。

The screen type is determined by the react-router. Would the reducer have any access to the router to determine which screen is being shown?

没有(一般来说)reducer 只能访问它们的状态片,所以虽然你的 reducer 可能会对 react router 动作做出反应(如果你将使用 react-router-redux - 见上文)来存储路由详细信息你需要,但原则上应该由您的选择器 and/or 连接的组件来构造/从状态树中提取给定组件所需的数据。

Are there any best practices for handling such a scenario?

我想使用 react-router-redux,引入一个中间件,它将触发 API 调用以响应您的操作,并将分派包含从 API 返回的数据的连续操作。您将在 reducer 中处理该操作,将数据存储在树中。

随机提示,如果您有 bodyTypeA、bodyTypeB 等组件,那么这些组件可以(甚至应该)保留信息(如果它们是 A 或 B)并将其传播给动作创建者。例如。如果您有一个名为 requestForId(ID) 的动作创建者,您会将签名修改为 requestForId(ID, type) 并且在您的组件/回调中(无论何时调用该动作创建者)您不仅会传递 ID,还会传递还有类型,即 bodyTypeA 会用 requestForId(ID, 'A').

调用它