useReducer
This hook is similar to the useState
but it also allows for custom state logic. If your state relies on some complex logic, useReducer
may be useful.
useReducer(reducerFunction, initialState)
The reducer function contains your custom state logic and the initialState
is the state object/value.
The useReducer
hook returns the current state
and a dispatch
method.
The dispatch
is used to call one of your logic written in the reducerFunction
.
Code example
import { useReducer } from 'react'
function UserForm() {
const [ state, dispatch ] = useReducer(
(state, action) => ({
...state,
...action
}),
{
first: "Ben",
last: "Dover"
})
return (
<div>
<input type="text"
value={state.first}
onChange={(e) => dispatch({ first: e.target.value })}
/>
<input type="text"
value={state.last}
onChange={(e) => dispatch({ last: e.target.value })}
/>
<div>
First: {state.first}
</div>
<div>
Last: {state.last}
</div>
</div>
);
}
function NameList() {
const [ state, dispatch ] = useReducer((state, action) => {
switch(action.type) {
case "SET_NAME":
return {...state, name: action.payload};
case "ADD_NAME":
return {...state, names: [...state.names, state.name], name: ""}
}
},
{
names: [],
name: ""
})
return (
<div className="App">
<ul>
{state.names.map((name, index) => (
<li key={index}>{name}</li>
))}
</ul>
<input
type="text"
value={state.name}
onChange={(e) =>
dispatch({type: "SET_NAME", payload: e.target.value})
}
/>
<button
onClick={() =>
dispatch({type: "ADD_NAME"})
}
>Add Name</button>
</div>
)
}
function App() {
return (
<div>
<NameList />
<UserForm />
</div>
);
}
export default App