如何在两个反应组件之间建立共享状态?

Jac*_*ack 30 javascript reactjs react-router

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

A. *_*dor 14

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

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

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
  );
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

反应文档:"在组件之间进行通信"

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


Sla*_*rch 12

在多个组件之间使用共享状态而不将应用程序代码重写到某些状态管理系统的最简单方法是use-between钩子。

在codesandbox中尝试这个例子

import React, { useState } from "react";
import { useBetween } from "use-between";

// Make a custom hook with your future shared state
const useFormState = () => {
  const [username, setUsername] = useState("");
  const [email, setEmail] = useState("");
  return {
    username, setUsername, email, setEmail
  };
};

// Make a custom hook for sharing your form state between any components
const useSharedFormState = () => useBetween(useFormState);

const ComponentA = () => {
  // Use the shared hook!
  const { username, setUsername } = useSharedFormState();
  return (
    <p>
      Username: <input value={username} onChange={(ev) => setUsername(ev.target.value)} />
    </p>
  );
};

const ComponentB = () => {
  // Use  the shared hook!
  const { email, setEmail } = useSharedFormState();
  return (
    <p>
      Email: <input value={email} onChange={(ev) => setEmail(ev.target.value)} />
    </p>
  );
};

const ComponentC = () => {
  // Use shared hook!
  const { email, username } = useSharedFormState();
  return (
    <p>
      Username: {username} <br />
      Email: {email}
    </p>
  );
};

export const App = () => (
  <>
    <ComponentA />
    <ComponentB />
    <ComponentC />
  </>
);
Run Code Online (Sandbox Code Playgroud)
  • 首先,我们创建useFormState自定义挂钩作为状态源。
  • 在下一步中,我们创建useSharedFormState使用的钩子useBetweenhook 的 hook。该钩子可以在任何可以读取或更新共享状态的组件中使用!
  • 最后一步是useSharedFormState在我们的组件中使用。

useBetween是一种调用任何钩子的方法。但这样状态就不会存储在React组件中。对于同一个钩子,调用的结果将是相同的。因此我们可以在不同的组件中调用一个钩子并在一种状态下协同工作。当更新共享状态时,使用它的每个组件也会更新。

  • 您可能想添加一个关于谁是这个很棒的库的作者的免责声明 - 我在这里做了一些可怕的事情](/sf/answers/5104233921/) 并提及您的库作为更好的方式。很想听听您对此的评论。 (2认同)

Cus*_*dio 9

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

例如,如果您打算开设一个中央商店,那么redux是一个不错的选择。但是,其他方法也是可能的:

  • 父母对孩子

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

    1. 回调函数
    2. 事件冒泡
  • 兄弟姐妹到兄弟姐妹

    1. 父组件
  • 任何对任何

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

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