Home > OS >  Use same useState in different components
Use same useState in different components

Time:07-13

I have a main app and two components. It looks something like this:

MainApp:

const MainApp = () => {
    return (
        <>
            <Component1 />
            <Component2 />
        </>
    );
};

Component1:

const Component1 = () => {
    const [state, setState] = useState(false)

    return (
        <>
            <button type="button" onClick={() => setState(state => !state)}>Toggle</button>
        </>
    );
};

Component2:

type Props = {
    state?: boolean;
};

const Component2 = ({ state }: Props) => {
    
    return (
        <>
            {state ? <p>Hello</p> : <p>Not hello</p>}
        </>
    );
};

Right now it obviously doesn't work since Component2 doesn't get the state from anywhere.

My problem is, how do I share the state between the two components, with the MainApp being the intermediary ? Do I create the useState variable in the MainApp instead of Component1, and then pass the state and setState to the toggle component (Component1), and pass the state to Component2, or is there a better way to do this ?

CodePudding user response:

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>
        </>
    )
}

CodePudding user response:

If you don't want to use useContext() or redux you would need to create the state in the MainApp and then pass it to Component1 and Component2.

// MainApp

const MainApp = () => {
    const [state, setState] = useState(false)

    return (
        <>
            <Component1 setState={setState} />
            <Component2 state={state} />
        </>
    );
};
// Component1

type Component1Props = {
  setState: React.Dispatch<React.SetStateAction<boolean>;
}

const Component1 = ({ setState } : Component1Props) => {
    return (
        <>
            <button type="button" onClick={() => setState((prev) => !prev)}>Toggle</button>
        </>
    );
};
// Component2

type Component2Props = {
    state?: boolean;
};

const Component2 = ({ state }: Component2Props) => {
    return (
        <>
            {state ? <p>Hello</p> : <p>Not hello</p>}
        </>
    );
};

CodePudding user response:

You can use useContext hook to share same data in your components.

https://reactjs.org/docs/hooks-reference.html#usecontext or tools like redux.

Your question is a good question but it doesn't get solved with one line of code.

I mean above sources are for general state management. If you have a really small app and you don't need to update state from different components etc. then you can just provide the data from parent of component 1 and 2

const MainApp = () => {
const [stateData,setStateData] = useState();

    return (
        <>
            <Component1 data={stateData}/>
            <Component2 data={stateData} />
        </>
    );
};

then access to that data in your components with props

const Component1 = (props) => {
   const dataFromParent = props.data
   const [stateData,setStateData] = useState(dataFromParent);
    return (
        <>
            <button type="button" onClick={() => setState(state => !state)}>Toggle</button>
        </>
    );
};
  • Related