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