Day 38/100 #100DaysOfCode #React #ReactNative
Hôm nay mình tìm hiểu về hooks useReducer trong React, nếu các bạn nào mà đã tìm hiểu về Redux, Redux-Saga thì cũng dễ hiểu về nhiệm vụ của useReducer
Ta cũng biết useReducer và useState tương đối giống nhau thôi
+ Nhưng có một điều khi ta dùng useState, để xử lý state có độ phức tạp thì gây ra khó khắn cho ta, ta cần viết nhiều function để update state,setState
+ Còn ở useReducer thì ta có thể cập nhật state thông qua các hành động(action), ta sẽ gửi lên một action, và chỉ việc nhận dạng action đó và update state lại thôi, giúp ta xử lý dữ liệu state phức tạp, tổ chức code của ta dễ hơn
DEMO:
useReducer(<reducer>, <initialState>)
+ reducer: ta sẽ cài đặt function xử lý các action gửi lên
+ initialState: giá trị state ban đầu, ta đưa vào
Okay giờ ta đi qua ví dụ luôn cho dễ hiểu, như đã giới thiệu về cú pháp của useReducer bên trên ta cần làm như sau:
Tạo một số action như sau:
/* CREATE ACTION */ export const ADD_TODO = "ADD_TODO"; export const REMOVE_TODO = "REMOVE_TODO"; export const EDIT_TODO = "EDIT_TODO";
* Tạo state ban đầu : Đầu tiên ta tạo state chứa dữ liệu ban đầu như dưới đây
/* CREATE STATE DATA */ const initialTodos = { todos: [ { id: 1, title: "Laravel 8", complete: false, }, { id: 2, title: "React Native", complete: false, }, ] }
* Tạo reducer function để xử lý các action gửi đến
/* CREATE REDUCER FUNCTION */ const reducer = (state, action) => { switch (action.type) { case ADD_TODO: { return { ...state, todos: [...state.todos, action.payload] } break; } case EDIT_TODO: { return { ...state, todos: state.todos.map(item => item.id==action.payload.id?action.payload:item) } break; } case REMOVE_TODO: { return { ...state, todos: state.todos.filter(item => item.id != action.payload.id) } break; } default: return state; break; } }
Bên trên ta cài đặt nhận dạng một số action gửi đến reducer để xử lý state
Okay để gửi một action lên ta sử dụng đến useReducer, nên ta cần khai báo như sau:
const [state, dispatch] = useReducer(reducer, initialTodos);
Sau đó gọi gửi một hành động như sau:
dispatch({ type: REMOVE_TODO, payload: todo })
+ type: chứa tên action
+ payload: chứa data của ta muốn gửi đến reducer xử lý
Okay nói chung nó khá đơn giản, bạn có thể chạy code dưới đây thư:
import React, { useReducer } from 'react' /* CREATE ACTION */ export const ADD_TODO = "ADD_TODO"; export const REMOVE_TODO = "REMOVE_TODO"; export const EDIT_TODO = "EDIT_TODO"; /* CREATE STATE DATA */ const initialTodos = { todos: [ { id: 1, title: "Laravel 8", complete: false, }, { id: 2, title: "React Native", complete: false, }, ] } /* CREATE REDUCER FUNCTION */ const reducer = (state, action) => { switch (action.type) { case ADD_TODO: { return { ...state, todos: [...state.todos, action.payload] } break; } case EDIT_TODO: { return { ...state, todos: state.todos.map(item => item.id==action.payload.id?action.payload:item) } break; } case REMOVE_TODO: { return { ...state, todos: state.todos.filter(item => item.id != action.payload.id) } break; } default: return state; break; } } function UseReducer() { const [state, dispatch] = useReducer(reducer, initialTodos); const add_todo = () => { const id = state.todos.length + 1; dispatch({ type: ADD_TODO, payload: { "id": id, "title": "Exampe useReducer , action " + id, "complete": false } }) } const edit_todo = (todo)=>{ todo.title = todo.title +"(Edit)"; dispatch({ type: EDIT_TODO, payload: todo }) } const remove_todo = (todo) => { dispatch({ type: REMOVE_TODO, payload: todo }) } return ( <div> <h1>UseReducer</h1> <ul> { state.todos.map(item => { return ( <li key={item.id}>{item.title} ---- <button onClick={() => remove_todo(item)} style={{ background: 'red' }}>remove todo</button> ---- <button onClick={() => edit_todo(item)} style={{ background: 'yellow' }}>edit todo</button> </li> ) }) } </ul> <button onClick={add_todo} style={{ background: 'green' }}>add todo</button> </div> ) } export default UseReducer