Manage complex state with React useReducer and useContext
source link: https://www.richardkotze.com/coding/react-hooks-usereducer-usecontext
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
This post will cover managing complex state at a feature level rather than the entire site. React hooks have enabled developers to have cleaner functional components which help to rationalise our component logic with easy.
Take useState
hook, it’s one line of code that can be used to manage the state of a component rather than having to create a class
component with the addition of boiler code. This is great because we are keeping simple things clear!
However, there are features that are inherently complex as they could have many nested child components and need to alter the state.
What optionsare there to manage this complexity in React ?
Photo by Ramón Salinero on Unsplash
Generally is good practice to keep it simple , which might lead you down the path of passing the setState
callback down the stack of components. The downside here is the mutation of state can become difficult to follow, by allowing child components to alter the state directly will make it unclear what the state object should look like. By not having a single source of truth where the mutation is managed then the result could be unexpected and requires an overhead to work out.
It is also worth considering how easy is it to test changes to state. Unit testing state through rendering components can be tricky and takes more time to build compared to pure functions.
Ideally you want to make it easy to follow changes to the component state and create unit tests which give confidence in the functionality working.
To help explain the idea I’ve created a classic Todo app in CodeSandbox.io.
Since the release of React 16.8 hooks were introduced. A hook which is helpful for managing more complex state is useReducer and as the docs say it’s an alternative to useState . This essentially borrows the good concepts from Redux but with less complex setup and boiler code to work with React.
const [todoList, dispatch] = useReducer(toDoReducer, initialState);
We can also use React Context . The benefit of combining useReducer
with context is being able to call the dispatch
function anywhere down the component tree without passing through props. Preventing the need to follow it through the component tree to find the callback.
const TodosDispatch = React.createContext(null); function App() { const [todoList, dispatch] = useReducer(toDoReducer, initialState); return ( <TodosDispatch.Provider value={dispatch}> ...ToDoApp </TodosDispatch.Provider> ); }
To access the context in child components the React hook useContext
can be used.
const dispatch = useContext(TodosDispatch);
This idea is recommended in the React docs, avoid passing callback down
Example React todo app with useReducer and useContext
Key pointsdemoed in the CodeSandbox
You can see how clean and simple the unit tests are for the reducer in the todo.spec.js
file. This will give confidence that the logic works as expected when state changes. These unit tests help manage complexity preventing regression when the reducer is updated to handle a new action.
- Key functions:
-
TodosContext
is where the reducerdispatch
callback will be stored -
toDoReducer
transforms the task list state based on actions e.g. add task -
initialState
contains one task object in an Array -
addAction
,markAction
,deleteAction
are all action creators which describe how to change the state
-
- Key components:
-
App
callsuseReducer
and passes thedispatch
function intoTodosDispatch.Provider
-
InputTask
user can enter task name and calls theaddAction
on submit -
TaskList
reads thetodoList
state and renders a numbered task list -
Action
is a generic button component which has access todispatch
to trigger done, undo and delete actions.
-
Explore the CodeSandbox ( useReducer and useContext React todo app ) below to see how it’s all connected.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK