How to Share States Between Components Using the Usestate() Hook in React

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.

How can I share state data between components using custom hooks?

You'll need to use Context, but it's not that bad..

create your context..

import React, { useState } from 'react';

export const FlashContext = React.createContext();

export const FlashProvider = ({ children }) => {
const [messages, setMessages] = useState([]);
return (
<FlashContext.Provider value={{ messages, setMessages }}>
{children}
</FlashContext.Provider>
);
};

wrap your components in the provider somewhere higher in the tree..

import React from "react";
import { FlashProvider } from "./flash-context";

const App = () => <FlashProvider><TheRest /></FlashProvider>;

export default App;

then use the context in your custom hook..

import React, { useContext } from "react";
import { FlashContext } from "./flash-context";

export default function useFlash() {
const { messages, setMessages } = useContext(FlashContext);

const showFlash = (message) => {
setMessages([...messages, message]);
};

const clearMessage = (index) => {
setMessages(messages.filter((_m, i) => index !== i));
};

return {
messages,
showFlash,
clearMessage
};
}

How to pass a value for useState hook from another component in ReactJS?

It seems like you want the Child component to simply toggle the display value of some content in the Parent component.

As you've defined them though they are not parent-child, but rather they are siblings. As such if they need to share state/behavior, then the solution is to lift state up to a common ancestor, App in this case.

<Route path="/content">
<Menu />
<div className="content-flexbox">
<Parent /> // <-- siblings
<Child /> // <-- siblings
</div>
<Footer />
</Route>

See: Lifting State Up

Move the showHideContent state and updater into the parent App component, pass down the showHideContent state to Parent and the toggleVisibility callback to the Child.

function Parent({ showHideContent }) {
return <div style={{ display: showHideContent }}>Some content here...</div>;
}

function Child({ onClick }) {
return (
<button type="button" onClick={onClick}>
Show/Hide Content
</button>
);
}

export default function App() {
const [showHideContent, setShowHideContent] = React.useState("none");

const toggleVisibility = () =>
setShowHideContent((value) => (value === "none" ? "block" : "none"));

return (
...
<Route path="/content">
<Menu />
<div className="content-flexbox">
<Parent showHideContent={showHideContent} />
<Child onClick={toggleVisibility} />
</div>
<Footer />
</Route>
...
);
}

Edit how-to-pass-a-value-for-usestate-hook-from-another-component-in-reactjs

Use same useState in different components

You should use contextApi to handle this. I have shared a sample code which helps you understand more about context api.

Context api helps you share the states and functions of a component
with other components inside the particular project.

In Filecontext.jsx you can see createContext which helps you in creating a context.

In App.jsx, we have created the states and functions which has to be shared among the components and wrapped the components which can access the datas with that context by importing it.

In Formcomponent.jsx, I am using useContext to use the states and functions created in the App.jsx.

Filecontext.jsx

import { createContext } from 'react'
export const Filecontext = createContext({});

App.jsx

import { Filecontext } from './Contexts/Filecontext';
import { useState } from 'react'

function App() {
const [name, setName] = useState("")
const [email, setEmail] = useState("")
const [mobileno, setMobileno] = useState("")
const showAlert = () => {
alert(`Hello ${name}`);
}

return (
<div className="App">
<Filecontext.Provider value={{ name, setName, email, setEmail, mobileno, setMobileno, showAlert }}>
<Formcomponent />
<Listcomponent />
</Filecontext.Provider>
</div>
);
}

export default App;

Formcomponent.jsx

import { Filecontext } from '../Contexts/Filecontext';
import { useContext } from 'react'

export default function Formcomponent() {
const { setName, setEmail, setMobileno, showAlert } = useContext(Filecontext)

return (
<>
<div className="form-group">
<label>Name : </label>
<input type="text" onChange={(e) => { setName(e.target.value) }} />
</div>
<div className="form-group">
<label>Email : </label>
<input type="email" onChange={(e) => { setEmail(e.target.value) }} />
</div>
<div className="form-group">
<label>Mobile No : </label>
<input type="number" onChange={(e) => { setMobileno(e.target.value) }} />
</div>
<div className="form-group">
<input type="submit" value="submit" onClick={() => { showAlert() }} />
</div>
</>
)
}

React Hooks, how to share state between two functions

import React, { useState } from "react";

function Home() {
const [mobileNavOpen, setMobileNavOpen] = useState(false);
return (
<div>
<button
onClick={() => setMobileNavOpen(true)}
type="button"
className="btn"
>
X
</button>
{mobileNavOpen && <MobileNav setMobileNavOpen={setMobileNavOpen} />}
</div>
);
}

function MobileNav({setMobileNavOpen}) {
return (
<div>
<button
onClick={() => setMobileNavOpen(false)}
type="button"
className="btn"
>
X
</button>
</div>
);
}

export default Home;
  1. you have to move the useState hook to the component body
  2. pass down the state setter function to your child component

How to share useState in different components

To share state between components, the recommended way is to use Context (https://reactjs.org/docs/context.html)

In short, crete a js file with where you export a React.createContext()

export const LangContext = React.createContext()

Then wrap your application in provider

<LangContext.Provider value={}>{children}</LangContext.Provider>

Then grab the state from the context by getting the context in the component

const context = React.useContext(LangContext)

How to transfer state between React components with hooks?

Classes and functional components (or func-comp as my mate calls them) are the same in respect to props.

You can pass props from parent to child in a functional component just like how you'd do with a class.


//Parent

const Parent = () => {

const [state, setState] = React.useState({ products: 1, isAvailable: true})

const addProduct = (data) => {
// Your function
}

return (
<Child product info={state} addProduct={addProduct} />

)

}

export default Parent

And in the child component you can receive the props typically the way you would will classes.


const Child = ({productInfo, addProduct}) => {
// Do what ever you like with the props
}

Cheers!

How to pass a state (hook) between separated files (components) in React

If state is shared between components, then you need to elevate that state to a common parent.

Then you can pass that state down to the children, probably as props or context.

For example:

function App() {
const [career, setCareer] = React.useState('');

return <>
<MenuPopupState career={career} onClick={setCareer} />
<Header career={career} />
</>
}

function MenuPopupState(props){
return (
<div>
<button onClick={() => props.onClick(props.career)}>
Press me
</button>
</div>
)
}

function Header(props){
return (
<div>
<a key={props.career.id}>
{props.career.name}
</a>
</div>
)
}


Related Topics



Leave a reply



Submit