React hook - useReducer - complex State & Action

React hook - useReducer - complex State & Action

·

2 min read

1. Các bước làm

1-1. Import useReducer

import { useReducer } from 'react'

1-2. Khởi tạo giá trị ban đầu

const initialState = { firstName: 'Ken', lastName: 'Trung' }

1-3. Tạo hàm reducer

  • Hàm này nhận 2 tham số
  • Tham số 1 là state muốn thay đổi giá trị
  • Tham số 2 là action
  • Tùy vào loại action mà thay đổi state tương ứng
const reducer = (state, action) => {
  switch (action.type) {
    case 'firstName':
      return { ...state, firstName: action.value }
    case 'lastName':
      return { ...state, lastName: action.value }
    default:
      return state
  }
}

1-4. Sử dụng useReducer

  • Hàm useReducer nhận 2 tham số
  • Tham số 1 là hàm reducer ở bước 1-3
  • Tham số 2 là biến initialState ở bước 1-2
  • Hàm useReducer trả về mảng 2 phần tử
  • Phần tử 1 là giá trị của state
  • Phần tử 2 là hàm để thay đổi state
const [user, dispatch] = useReducer(reducer, initialState)
const { firstName, lastName } = user

return (
  <>
    <input 
      value={firstName} 
      onChange={e => dispatch({ type: 'firstName', value: e.target.value })}
    />
    <input 
      value={lastName}
      onChange={e => dispatch({ type: 'lastName', value: e.target.value })}
    />
    <p>User Name: {firstName} - {lastName}</p>
  </>
)

2. Toàn bộ file

import React, { useReducer } from 'react'

const initialState = { firstName: 'Ken', lastName: 'Trung' }

const reducer = (state, action) => {
  switch (action.type) {
    case 'firstName':
      return { ...state, firstName: action.value }
    case 'lastName':
      return { ...state, lastName: action.value }
    default:
      return state
  }
}

export default function HookCounter() {
  const [user, dispatch] = useReducer(reducer, initialState)
  const { firstName, lastName } = user
  return (
    <>
      <input 
        value={firstName} 
        onChange={e => dispatch({ type: 'firstName', value: e.target.value })}
      />
      <input 
        value={lastName}
        onChange={e => dispatch({ type: 'lastName', value: e.target.value })}
      />
      <p>User Name: {firstName} - {lastName}</p>
    </>
  )
}

3. Demo