Javascript 如何在两个 React 组件之间创建共享状态?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38901106/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 22:01:11  来源:igfitidea点击:

How to make a shared state between two react components?

javascriptreactjsreact-router

提问by Hyman

I have 2 react components that need to share a state, react-router shows component A, which takes some inputs and adds it to its state, after the state has been successfully updated, I want to redirect to component B, where the user adds some more inputs and updates the same state as component A to build an object with inputs from A and B before I submit a post request to my api to save the data from both component A and B. How can I accomplish this, is there a way to use react-router, or do I have to set up a parent/child relationship between the components?

我有 2 个需要共享状态的 react 组件,react-router 显示组件 A,它接受一些输入并将其添加到其状态,在成功更新状态后,我想重定向到用户添加的组件 B在向我的 api 提交发布请求以保存来自组件 A 和 B 的数据之前,我需要更多的输入并更新与组件 A 相同的状态,以使用来自 A 和 B 的输入构建一个对象。我如何才能做到这一点,是否有使用 react-router 的方法,还是必须在组件之间建立父/子关系?

采纳答案by A. Vidor

What you want is to implement some object that stores your state, that can be modified using callback functions. You can then pass these functions to your React components.

你想要的是实现一些存储你的状态的对象,可以使用回调函数进行修改。然后你可以将这些函数传递给你的 React 组件。

For instance, you could create a store:

例如,您可以创建一个商店:

function Store(initialState = {}) {
  this.state = initialState;
}
Store.prototype.mergeState = function(partialState) {
  Object.assign(this.state, partialState);
};

var myStore = new Store();

ReactDOM.render(
  <FirstComponent mergeState={myStore.mergeState.bind(myStore)} />,
  firstElement
  );
ReactDOM.render(
  <SecondComponent mergeState={myStore.mergeState.bind(myStore)} />,
  secondElement
  );

Now, both the FirstComponentand SecondComponentinstances can call this.props.mergeState({ . . .})to assign state to the same store.

现在,FirstComponentSecondComponent实例都可以调用this.props.mergeState({ . . .})将状态分配给同一个存储。

I leave Store.prototype.getStateas an exercise for the reader.

我留给Store.prototype.getState读者作为练习。

Note that you can always pass the store (myStore) itself to the components; it just feels less react-y to do so.

请注意,您始终可以将 store ( myStore) 本身传递给组件;这样做只是感觉不那么反应。

Here is some more documentation that might be of interest:

以下是一些您可能感兴趣的文档:

React Docs: "Communicate Between Components"

React Docs:“组件间通信”

For communication between two components that don't have a parent-child relationship, you can set up your own global event system. Subscribe to events in componentDidMount(), unsubscribe in componentWillUnmount(), and call setState() when you receive an event. Flux pattern is one of the possible ways to arrange this.

对于没有父子关系的两个组件之间的通信,您可以设置自己的全局事件系统。在 componentDidMount() 中订阅事件,在 componentWillUnmount() 中取消订阅,并在收到事件时调用 setState()。通量模式是一种可能的安排方式。

回答by Custodio

The dependency type between the components will define the best approach.

组件之间的依赖类型将定义最佳方法。

For instance, redux is a great option if you plan to have a central store. However other approaches are possible:

例如,如果您计划拥有一个中央存储,redux 是一个不错的选择。然而,其他方法也是可能的:

  • Parent to Child

    1. Props
    2. Instance Methods
  • Child to Parent

    1. Callback Functions
    2. Event Bubbling
  • Sibling to Sibling

    1. Parent Component
  • Any to Any

    1. Observer Pattern
    2. Global Variables
    3. Context
  • 父母对孩子

    1. 道具
    2. 实例方法
  • 孩子对父母

    1. 回调函数
    2. 事件冒泡
  • 兄妹对兄妹

    1. 父组件
  • 任何对任何

    1. 观察者模式
    2. 全局变量
    3. 语境

Please find more detailed information about each of the approaches here

在此处找到有关每种方法的更多详细信息

回答by Harkirat Saluja

Either you can set up a parent child relationship then you can pass data to child components as props.

您可以设置父子关系,然后可以将数据作为道具传递给子组件。

Else, if you want to create interaction between 2 components which are not related to either(parent/child) you can either check out fluxor even better redux.

否则,如果您想在与任何一个(父/子)无关的 2 个组件之间创建交互,您可以检查通量或更好的redux

I would say you should go with redux.See Here why

我会说你应该使用 redux。看这里为什么

回答by Makan

You can build custom React hooks to share a statebetween components, I made one here. You can use it by downloading use-linked-state.jsfile.

您可以构建自定义 React 钩子以state在组件之间共享一个,我在这里做了一个。您可以通过下载use-linked-state.js文件来使用它。

After importing useStateGatewayhook, declare a gateway in parent component and pass it down to your child components

导入useStateGatewayhook 后,在父组件中声明网关并将其传递给您的子组件

import {useStateGateway} from "use-linked-state";
const myGateway = useStateGateway({partA:null, partB:null});
return (
  <>
    <ComponentA gateway={myGateway}>
    <ComponentB gateway={myGateway}>
    <ComponentPost gateWay={myGateway}>
  </>
  )

Then you have access shared state between those three components by a custom useLinkedState hook

然后您可以通过自定义 useLinkedState 钩子访问这三个组件之间的共享状态

import { useLinkedState } from "use-linked-state";

export default function ComponentA({gateway}){

  const [state, setState] =  useLinkedState(gateway);

  <your logic>

}

In your logic ComponentAand ComponentBwould be responsible for their part in shared object {partA:"filled by ComponentA", partB:"filled by componentB"}. Finally ComponentPostpost the result if partAand partBof shared object were valid.

在你的逻辑ComponentAComponentB共享对象中会负责自己的部分{partA:"filled by ComponentA", partB:"filled by componentB"}。最后ComponentPost发布的结果,如果partApartB共享对象是有效的。

In this way you can compose components and make connection between them to talk to each other.

通过这种方式,您可以组合组件并在它们之间建立连接以相互通信。