Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for React hooks: useContext
Abdullah Furkan Özbek
Abdullah Furkan Özbek

Posted on • Edited on • Originally published atnotes.furkanozbek.com

     

React hooks: useContext

State Management

While developing React application, you are most likely will have different pages, components to render. In this case most components itself has the hooks we can use(functional components) to create component state. And you also pass some internal state as a prop to subcomponents.

// components/TodoList.jsconstTodoList=()=>{const[todoList,setTodoList]=useState([]);const[user,setUser]=useState({})return(<><Headeruser={user}/><Bodyuser={user}/><Footeruser={user}/>{todoList.map(todo=><Todotodo={todo}key={todo.id}user={user}/>)}</>);}
Enter fullscreen modeExit fullscreen mode

Context API

React Context is a state management API which is in the React's core package. We can use Context API for pretty much anything that we need from state manegement library. Main purpose of using it is sharing data across multiple components without passing them via props.

All context consumers arere-rendered whenever a value passed to the Provider changes. One way to fix this is to use useMemo hook which wouldmemoize the value object. It would only be re-created whendependency value changes.

In this article we will try to manage our todoList using Context API

Creating TodoListContext

// contexts/todoListContext.jsconstTodoListContext=createContext([]);constTodoListContextProvider=(props)=>{const[todoList,setTodoList]=useState([]);// Only rerender when todoList changesconstvalue=useMemo(()=>[todoList,setTodoList],[todoList]);return(<TodoListContext.Providervalue={value}>{props.children}</TodoListContext.Provider>)}
Enter fullscreen modeExit fullscreen mode

We can also create a custom hook and manage some logic inside of our hook.

// contexts/todoListContext.jsconstuseTodoList=()=>{constcontext=useContext(TodoListContext);if(!context){thrownewError("useTodoList must be used inside TodoListProvider")}returncontext;}
Enter fullscreen modeExit fullscreen mode

After that we can use this hook in the components

// components/TodoList.jsconstTodoList=()=>{const[todoList,setTodoList]=useTodoList();constaddTodo=(todo)=>setTodoList([...todoList,todo]);return(<>{todoList.map(todo=><Todotodo={todo}key={todo.id}/>)}<buttononClick={()=>{addTodo({id:Math.random(),name:"New Todo"})}}>Add Todo</button></>);}
Enter fullscreen modeExit fullscreen mode

Then what we can do to improve the hook is tha we can remove any external logic from components and adding them to the hook itself. So we can remove addTodo function from here and move it to the useTodoList hook. And we can also use useReducer instead of useState in this situation.

useReducer can reduce the complexity of the actions and increase usability

// contexts/todoListContext.jsconsttodoReducer=(state,action)=>{switch(action.type){case"NEW":return[...state,action.payload]case"DELETE":returnstate.filter(todo=>todo.id!=action.payload);default:returnstate;}}constuseTodoList=()=>{constcontext=useContext(TodoListContext);if(!context){thrownewError("useTodoList must be used inside TodoListProvider")}const[todoList,setTodoList]=context;// Hook FunctionsconstaddTodo=(todo)=>dispatch({type:"NEW",payload:todo})constremoveTodo=(todoId)=>dispatch({type:"DELETE",payload:todoId});return{todoList,setTodoList,addTodo,removeTodo};}
Enter fullscreen modeExit fullscreen mode

Final code will look like this;

constTodoListContext=createContext([]);consttodoReducer=(state,action)=>{switch(action.type){case"NEW":return[...state,action.payload]case"DELETE":returnstate.filter(todo=>todo.id!=action.payload);default:returnstate;}}constTodoListContextProvider=(props)=>{const[state,dispatch]=useReducer(todoReducer,[]);constvalue=useMemo(()=>[state,dispatch],[state]);return(<TodoListContext.Providervalue={value}>{props.children}</TodoListContext.Provider>)}constuseTodoList=()=>{constcontext=useContext(TodoListContext);if(!context){thrownewError("useTodoList must be used inside TodoListProvider")}const[state,dispatch]=context;// Hook FunctionsconstaddTodo=(todo)=>dispatch({type:"NEW",payload:todo})constremoveTodo=(todoId)=>dispatch({type:"DELETE",payload:todoId});return{todos:state,dispatch,addTodo,removeTodo};}export{TodoListContextProvider,useTodoList
Enter fullscreen modeExit fullscreen mode

Reference

Application State Management with React

How to use React Context effectively

Hooks API Reference - React

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Front End Developer 👨🏻‍💻 | Cosmos Enthusiast 🌌 | Loves React and Javascript 🧡
  • Location
    Istanbul
  • Education
    Istanbul University Computer Engineering
  • Work
    Front End Developer
  • Joined

More fromAbdullah Furkan Özbek

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp