以下の内容はhttps://uga-box.hatenablog.com/entry/2024/12/23/000000より取得しました。


【JavaScript】immer

immerというJavaScriptのライブラリの使い方を調べた

immerjs.github.io

immerは、JavaScript でイミュータブルなデータ構造を簡単に操作するためのライブラリ

proxy を使って、オブジェクトを一時的に「仮想的にミュータブルに扱える」ようにしてくれる

よく使うのは ReactのuseStateでの操作で、状態を更新する処理が簡潔に書けるようになる

React & Immer | Immer

  const handleToggle = useCallback((id) => {
    setTodos(
      produce((draft) => {
        const todo = draft.find((todo) => todo.id === id);
        todo.done = !todo.done;
      })
    );
  }, []);

またuseReducerでの操作も簡潔になる

const TodoList = () => {
    const [todos, dispatch] = useReducer(
        produce((draft, action) => {
            switch (action.type) {
                case "toggle":
                    const todo = draft.find(todo => todo.id === action.id)
                    todo.done = !todo.done
                    break
                case "add":
                    draft.push({
                        id: action.id,
                        title: "A new todo",
                        done: false
                    })
                    break
                default:
                    break
            }
        }),
        [ /* initial todos */ ]
    )

    const handleToggle = useCallback(id => {
        dispatch({
            type: "toggle",
            id
        })
    }, [])

    const handleAdd = useCallback(() => {
        dispatch({
            type: "add",
            id: "todo_" + Math.random()
        })
    }, [])
}

immerが特に便利なのは、ネストされたオブジェクトの操作

たとえば、普通にネストされたオブジェクトを操作すると、毎回手動で全ての親オブジェクトをコピーしなければならない

const state = {
  user: {
    profile: {
      name: 'Alice',
      age: 25,
    },
  },
};

const newState = {
  ...state,
  user: {
    ...state.user,
    profile: {
      ...state.user.profile,
      name: 'Bob',
    },
  },
};

このコード、変更箇所は name だけなのに、コピーが多くて面倒である

こんな時にimmer を使うと、ネストされたオブジェクトのコピーを気にせず、以下のように書ける

import produce from 'immer';

const state = {
  user: {
    profile: {
      name: 'Alice',
      age: 25,
    },
  },
};

const newState = produce(state, draft => {
  draft.user.profile.name = 'Bob';
});



以上の内容はhttps://uga-box.hatenablog.com/entry/2024/12/23/000000より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14