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?
-
1Have a look at [redux](https://github.com/reactjs/redux). – Mario Tacke Aug 11 '16 at 16:00
-
1Often with react state is managed through flux/redux or something. Personally, I like redux – aw04 Aug 11 '16 at 16:00
-
That was my first idea, unfortunately we are not implementing redux untill a few sprints down the road. I have to figure out another solution for handling this with just react and react-router. . . but it's a bit tricky – Jack Aug 11 '16 at 16:06
-
2That makes very little sense. It seems you would either decide you need redux now, or wait on the tasks that would benefit from it – aw04 Aug 11 '16 at 17:15
-
1I have this exact problem, but it isn't well answered with respect to react-router, as far as I can tell, where components are more like constructors. I admit I know zero about redux, but react-router doesn't really have any examples for integrating with it. – Stuart Watt Aug 15 '16 at 16:56
-
1I seem late here, but this article helped me a lot. https://medium.com/@ruthmpardee/passing-data-between-react-components-103ad82ebd17 It explains how to pass data between components in a Parent-to-Child relationship or vice versa, and also between sibblings. – Delali Jul 01 '18 at 01:24
6 Answers
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:
Parent to Child
- Props
- Instance Methods
Child to Parent
- Callback Functions
- Event Bubbling
Sibling to Sibling
- Parent Component
Any to Any
- Observer Pattern
- Global Variables
- Context
Please find more detailed information about each of the approaches here

- 8,594
- 15
- 80
- 115
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.
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 FirstComponent
and SecondComponent
instances can call this.props.mergeState({ . . .})
to assign state to the same store.
I leave Store.prototype.getState
as an exercise for the reader.
Note that you can always pass the store (myStore
) itself to the components; it just feels less react-y to do so.
Here is some more documentation that might be of interest:
React Docs: "Communicate Between Components"
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.

- 2,502
- 1
- 16
- 24
-
React beginner here: I'm curious why it is impractical to artificially introduce a parent into a child-child relationship. Wouldn't the place where either child gets instantiated also be a place that could reference a global parent and share its state very much like you are sharing myStore? – Corey Alix Mar 25 '18 at 16:41
-
@CoreyAlix Can you be a little clearer about the scenario you are proposing? What is a "global parent", and what does it mean for a child to "reference a global parent"? If you are asking why it is not always practical to store state on a common parent of two nodes, this breaks down into two separate issues: (1) Always finding or creating a common parent; (2) Piping the information from a common parent to the relevant children in a way that isn't spaghetti. – A. Vidor Mar 25 '18 at 22:07
-
1@CoreyAlix (2) is the kicker. I think it's about choosing the right tool for the job: React components make sense when the nodes they represent, and the channels of information they create, follow/simplify the conceptual shape of the application. When you begin introducing ad-hoc nodes and properties in response to new pieces of shared state appearing in the conceptual model, it can turn into a hairball! But if you're just asking "why a vanilla Object instead of a 'global state-holder' React component?": I can imagine situations where either approach has advantages. – A. Vidor Mar 25 '18 at 22:12
-
I was wondering why the vanilla store solution vs a react state component, yes. The react state could be used to bind to the properties of the children and therefore setup a parent->child binding. One of the properties could be the parent/state setter itself, like in your proposed solution, allowing the children to set the "global" state and the bound properties of both children will get refreshed. I'm not suggesting I know better, I'm curious as to why a vanilla solution make more sense? – Corey Alix Mar 26 '18 at 00:09
-
@A.Vidor How can i achieve this in HOC? plz check this post https://stackoverflow.com/questions/49707746/hoc-how-to-update-state-data-in-all-innercomponent/49707831#49707831 – Balasubramanian Apr 07 '18 at 20:26
-
1
-
The link to the react doc seems dead. Here is a backup: https://zhenyong.github.io/react/tips/communicate-between-components.html – @A.Vidor is this the correct one? – Philzen Jul 10 '22 at 16:45
The easiest way to use a shared state between several components without rewriting your application's code to some state management system is use-between
hook.
Try this example in 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 />
</>
);
- For first, we create
useFormState
custom hook as a source for our state. - In the next step, we create
useSharedFormState
hook who usesuseBetween
hook inside. That hook can be used in any component who can read or update the shared state! - And the last step is using
useSharedFormState
in our components.
useBetween
is a way to call any hook. But so that the state will not be stored in the React component. For the same hook, the result of the call will be the same. So we can call one hook in different components and work together on one state. When updating the shared state, each component using it will be updated too.

- 409
- 4
- 9
-
2You may wanna add a disclaimer about who's the author of this awesome library BTW - i made [something awful over here](https://stackoverflow.com/a/72917627/1246547) and mention your library as a better way. Would love to hear your comment(s) on that. – Philzen Jul 08 '22 at 22:38
I'll be going straight to hell for this:
// src/hooks/useMessagePipe.ts
import { useReducer } from 'react'
let message = undefined
export default function useMessagePipe(): { message: string | undefined, sendMessage: (filter: string) => void } {
const triggerRender = useReducer((bool) => !bool, true)[1]
function update(term: string) {
message = message.length > 0 ? message : undefined
triggerRender()
}
return { message: message, sendMessage: update }
}
You can then use this in any component anywhere in your applications' component hierarchy to send a message:
// src/components/ExampleInputToHell.jsx:
import useMessagePipe from 'src/hooks/useMessagePipe'
export const ExampleInputToHell() = () => {
const { sendMessage } = useMessagePipe()
return <input onChange={(e) => sendMessage(' Hell-O : ' + e.target.value)} />
}
… and consume the message any component anywhere in your applications' component hierarchy:
// src/components/ExampleOutputInHell.jsx
import useMessagePipe from 'src/hooks/useMessagePipe'
export const ExampleOutputInHell() {
const { message } = useMessagePipe()
return <p>{message}</p>
}
Explanation
let message
outside theuseMessagePipe
-closure holds a global state, that (as far is the theory goes) gets surrounded in it's own module scope- as react's functional component logic will know nothing about that state,
triggerRender
– a version of a dirty hack that's actually mentioned on the React FAQ – needs to be applied to signal to react that all components consuming this function are asked to re-evaluate (re-render).
Disclaimer
This is a global state, meaning: all components using useMessagePipe
see the same message and access the same update function, application-wide. If you want to have a new "channel" between two other components, you need to create another hook referring to another global state holder outside the closure (like message
in this example).
If you know any better and have the time and resources, you probably don't want to go down this muddy road to perdition and instead learn how to properly useContext
or (an easier way) give useBetween
by @Slava Birch a star.
But if you just want a quick and dirty solution to pipe a piece of data between components right now … well this ~10 lines of code made my day for a simple task at hand and worked flawless so far. However my gut feeling says something is going to break if used for important things, hence any additions & theories on the conditions under which it will break are highly welcome.

- 3,945
- 30
- 46
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 flux or even better redux.
I would say you should go with redux.See Here why

- 7,768
- 5
- 47
- 73
You can build custom React hooks to share a state
between components, I made one here. You can use it by downloading use-linked-state.js
file.
After importing useStateGateway
hook, declare a gateway in parent component and pass it down to your child components
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
import { useLinkedState } from "use-linked-state";
export default function ComponentA({gateway}){
const [state, setState] = useLinkedState(gateway);
<your logic>
}
In your logic ComponentA
and ComponentB
would be responsible for their part in shared object {partA:"filled by ComponentA", partB:"filled by componentB"}
.
Finally ComponentPost
post the result if partA
and partB
of shared object were valid.
In this way you can compose components and make connection between them to talk to each other.