React useReducer 使用及 useImmerReducer

发布于:2024-06-22 ⋅ 阅读:(45) ⋅ 点赞:(0)

useReducer 实际上是以数组上的 reduce() 方法命名的。
传递给 reduce 的函数被称为 “reducer”。它接受 目前的结果 和 当前的值,然后返回 下一个结果。
React 中的 reducer 和这个是一样的:它们都接受 目前的状态 和 action ,然后返回 下一个状态。

reduce

const arr = [1, 2, 3, 4, 5];
const sum = arr.reduce(
  (result, number) => result + number
); // 1 + 2 + 3 + 4 + 5

useReducer

// 定义 reducer
const reducer = (state, action){
	const { type, payload } = action
	// case 块包装到 { } 花括号中,这样在不同 case 中声明的变量就不会互相冲突。
	// case 通常应该以 return 或 break 结尾,避免代码进入 到下一个 case!
	switch(type){
		case 'add': {
			return state + payload.num
		}
		case 'substract': {
			return state - payload.num
		}
		default: {
	      	throw Error('未知 action: ' + action.type);
	    }
	}
}

// 声明 useReducer
const [tasks, dispatch] = useReducer(reducer, 0);

// 使用 useReducer
function handleAddTask(text) {
    dispatch({
        type: 'add',
        payload: {
        	num: 100
        }
    });
}

useReduce 同 useState一样, 返回的state是不能直接修改的, 而 Immer 提供了一种特殊的 draft 对象,你可以通过它安全的修改 state。在底层,Immer 会基于当前 state 创建一个副本。

useImmerReducer

// 引入
import { useImmerReducer } from 'use-immer';
// 声明
const initialTasks = [
  {id: 0, text: '参观卡夫卡博物馆', done: true},
  {id: 1, text: '看木偶戏', done: false},
  {id: 2, text: '打卡列侬墙', done: false},
];
const [tasks, dispatch] = useImmerReducer(tasksReducer, initialTasks);
// 定义 reducer
function tasksReducer(draft, action) {
  switch (action.type) {
    case 'added': {
      draft.push({
        id: action.id,
        text: action.text,
        done: false,
      });
      break;
    }
    case 'changed': {
      const index = draft.findIndex((t) => t.id === action.task.id);
      draft[index] = action.task;
      break;
    }
    case 'deleted': {
      return draft.filter((t) => t.id !== action.id);
    }
    default: {
      throw Error('未知 action:' + action.type);
    }
  }
}
// 使用 useReducer
function handleAddTask(text) {
    dispatch({
      type: 'added',
      id: nextId++,
      text: text,
    });
  }

网站公告

今日签到

点亮在社区的每一天
去签到