我有 2 个需要共享状态的 react 组件,react-router 显示组件 A,它接受一些输入并将其添加到其状态,在成功更新状态后,我想重定向到组件 B,用户添加在我向我的 api 提交发布请求以保存来自组件 A 和 B 的数据之前,我需要更多的输入并更新与组件 A 相同的状态,以使用来自 A 和 B 的输入构建一个对象。我该如何实现这一点,是否有使用 react-router 的方法,还是必须在组件之间建立父/子关系?
如何在两个 React 组件之间创建共享状态?
您想要的是实现一些存储您的状态的对象,可以使用回调函数对其进行修改。然后你可以将这些函数传递给你的 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
);
现在,FirstComponent
和SecondComponent
实例都可以调用this.props.mergeState({ . . .})
将状态分配给同一个存储。
我留给Store.prototype.getState
读者作为练习。
请注意,您始终可以将 store ( myStore
) 本身传递给组件;这样做只是感觉不那么react。
以下是一些您可能感兴趣的文档:
对于没有父子关系的两个组件之间的通信,您可以设置自己的全局事件系统。在 componentDidMount() 中订阅事件,在 componentWillUnmount() 中取消订阅,并在收到事件时调用 setState()。通量模式是一种可能的安排方式。
在多个组件之间使用共享状态而不将应用程序的代码重写到某个状态管理系统的最简单方法是use-between
钩子。
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 />
</>
);
- 首先,我们创建
useFormState
自定义钩子作为我们状态的来源。 - 在下一步中,我们创建在内部
useSharedFormState
使用useBetween
钩子的钩子。该钩子可用于任何可以读取或更新共享状态的组件! - 最后一步是
useSharedFormState
在我们的组件中使用。
useBetween
是一种调用任何钩子的方法。但是这样状态就不会存储在 React 组件中。对于同一个钩子,调用的结果是一样的。所以我们可以在不同的组件中调用一个钩子并在一种状态上协同工作。当更新共享状态时,使用它的每个组件也将被更新。
您可以构建自定义 React 钩子以state
在组件之间共享一个,我在这里做了一个。您可以通过下载use-linked-state.js
文件来使用它。
导入useStateGateway
hook 后,在父组件中声明网关并将其传递给您的子组件
import {useStateGateway} from "use-linked-state";
const myGateway = useStateGateway({partA:null, partB:null});
return (
<>
<ComponentA gateway={myGateway}>
<ComponentB gateway={myGateway}>
<ComponentPost gateWay={myGateway}>
</>
)
然后您可以通过自定义 useLinkedState 钩子访问这三个组件之间的共享状态
import { useLinkedState } from "use-linked-state";
export default function ComponentA({gateway}){
const [state, setState] = useLinkedState(gateway);
<your logic>
}
在你的逻辑ComponentA
和ComponentB
共享对象中会负责自己的部分{partA:"filled by ComponentA", partB:"filled by componentB"}
。最后ComponentPost
发布的结果,如果partA
与partB
共享对象是有效的。
通过这种方式,您可以组合组件并在它们之间建立连接以相互通信。