How to make a shared state between two react components?
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.
How can we share a state variables between two React components on the same page?
In this case, if you have given a pascal case naming for the text input such as function TextInput(){...}
, then react will consider this as a separate component even if this is defined in the same file. This is why the state variables of the App
component are not within the scope of TextInput
You can mitigate this by following either of the following approcahes,
- Make text input a normal function which returns the JSX
function textInput(){
// the state variable 'success' and 'setSuccess' will be normally accessible here
return(
<div>
<input type="text" />
<div>
)
}
//return for the 'App' component
return(
<>
{textInput()}
</>
)
Passing the state as
props
to theTextInput
componentIf you follow this approach, then you can have the
TextInput
component in a separate file as well
//parent 'App' component
function App(){
const [success, setSuccess] = useState(false);
return(
<>
<TextInput success={success} setSuccess={setSuccess}></TextInput>
</>
)
}
function TextInput(props){
const {success, setSuccess} = props;
// In here you can refer success and setSuccess normally as you would even if this is in a separate file
}
How to share state between state between React sibling component functions?
I suppose the best answer is: it depends.
However, the most simple solution would be to hold the value in a parent component and pass it down to both child components through props.
If you want to skip few nesting levels, you could reach for React context or state management tools like redux but that is already a heavy tool. Hard to say what exactly is best in your case with context you shared so far.
Shared state between Parent and Child component
setCollectionIds(collectionIds.push(newId))
Array.push
is not returning the array but the length of the array
const array = [1]
console.log(array.push(2)) // prints 2 because array.length is 2
You are effectively setting state to a number, not array, you can do:
setCollectionIds([...collectionIds, newId])
or
setCollectionIds(collectionIds.concat([newId]))
Is it possible to share states between components using the useState() hook in React?
If you are referring to component state, then hooks will not help you share it between components. Component state is local to the component. If your state lives in context, then useContext
hook would be helpful.
Fundamentally, I think you misunderstood the line "sharing stateful logic between components". Stateful logic is different from state. Stateful logic is stuff that you do that modifies state. For e.g., a component subscribing to a store in componentDidMount()
and unsubscribing in componentWillUnmount()
. This subscribing/unsubscribing behavior can be implemented in a hook and components which need this behavior can just use the hook.
If you want to share state between components, there are various ways to do so, each with its own merits:
1. Lift State Up
Lift state up to a common ancestor component of the two components.
function Ancestor() {
const [count, setCount] = useState(999);
return <>
<DescendantA count={count} onCountChange={setCount} />
<DescendantB count={count} onCountChange={setCount} />
</>;
}
This state sharing approach is not fundamentally different from the traditional way of using state, hooks just give us a different way to declare component state.
2. Context
If the descendants are too deep down in the component hierarchy and you don't want to pass the state down too many layers, you could use the Context API.
There's a useContext
hook which you can leverage on within the child components.
3. External State Management Solution
State management libraries like Redux or Mobx. Your state will then live in a store outside of React and components can connect/subscribe to the store to receive updates.
Share state between components
I think you just need 'value' to accept a prop passed into it on the switch button. Then wherever you use switch button just pass a boolean value into it from state e.g.
<SwitchButton enabled={this.state.switchEnabled}/>
As for setting state 'globally' so this.state.switchEnabled
can be updated from various places / accessible all over the app you need to look into state management tools like Redux (or I hear 'React Hooks' is now a thing and preferred....)
Related Topics
Get Word Under Tap from Uiwebview Using JavaScript
How to Wait in Node.Js (Javascript)? L Need to Pause for a Period of Time
Anything Similar in JavaScript to Ruby's #{Value} (String Interpolation)
Angular 2 Optional Route Parameter
Can a Site Invoke a Browser Extension
Parsing JSON Giving "Unexpected Token O" Error
Extending an Object in JavaScript
Capture Browser Console Logs with Capybara
JavaScript for "Add to Home Screen" on Iphone
What Do {Curly Braces} Around JavaScript Variable Name Mean
The .Replace() Method Does Change the String in Place
Prevent Long Running JavaScript from Locking Up Browser
Template Language That Works on Both Server and Client
Triggering Onclick Event Using Middle Click
How Would You Overload the [] Operator in JavaScript
Firebase.Database Is Not a Function