react hooks(useImmer)

28 阅读1分钟

安装:

地址:www.npmjs.com/package/use…

npm install immer use-immer

useImmer代码例子:

import React from "react";
import { useImmer } from "use-immer";

function UseImmerView() {
  const [state, updateState] = useImmer({ count: 0 });

  const increment = () => {
    updateState(draft => {
      draft.count += 1;
    });
  };

  const decrement = () => {
    updateState(draft => {
      draft.count -= 1;
    });
  };

  return (
    <div>
      <h2>Count: {state.count}</h2>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
}

export default UseImmerView;

useImmerReducer 代码例子

import { useCallback } from "react";
import type { Draft } from "immer";
import { useImmerReducer } from "use-immer";

type Todo = { id: number; text: string; done: boolean };

function UseImmerReducerExample() {
  type State = { todos: Todo[] };

  type Action =
    | { type: "add"; text: string }
    | { type: "toggle"; id: number };

  const initialState: State = { todos: [] };

  function reducer(draft: Draft<State>, action: Action) {
    switch (action.type) {
      case "add":
        draft.todos.push({ id: Date.now(), text: action.text, done: false });
        return;
      case "toggle": {
        const t = draft.todos.find((x) => x.id === action.id);
        if (t) t.done = !t.done;
        return;
      }
      default:
        return;
    }
  }

  const [state, dispatch] = useImmerReducer(reducer, initialState);
  const [text, setText] = React.useState("");

  const onAdd = useCallback(() => {
    if (!text.trim()) return;
    dispatch({ type: "add", text: text.trim() });
    setText("");
  }, [text, dispatch]);

  return (
    <div className="immer-reducer-root">
      <h3>useImmerReducer - Todos</h3>
      <div>
        <input
          value={text}
          onChange={(e) => setText(e.target.value)}
          placeholder="New todo"
        />
        <button onClick={onAdd}>Add</button>
      </div>
      <ul className="immer-todo-list">
        {state.todos.map((t) => (
          <li key={t.id} className={t.done ? "done" : "not-done"}>
            <label>
              <input
                type="checkbox"
                checked={t.done}
                onChange={() => dispatch({ type: "toggle", id: t.id })}
              />
              {" "}
              {t.text}
            </label>
          </li>
        ))}
      </ul>
    </div>
  );
}

// Optionally export the reducer example if other modules want to import it
export { UseImmerReducerExample };