Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

Organization

immerで複雑な構造のオブジェクトを扱う

複雑な構造のオブジェクトに何か値を追加する際、現在の構造を壊さずに値を追加しなければならないのでスプレッド演算子をたくさん使ったコードになりがちです。

イメージとしてはこんな感じのやつです。

const user; // 変更前のユーザー。複雑な構造をしている
const additionalHoge = ['hoge', 'huga']; // 追加したいデータ

const newUser = {
  ...user,
  detail: {
    ...user.detail,
    hoge: [...user.detail.hoge, ...additionalHoge],
  }
}

こういう雰囲気のコードをいい感じにリファクタできるimmerというライブラリを最近知りました。mobxの作者の方が作ったライブラリみたいです。

immerを使うと上のやつはこんな感じで書き直せます。
元の変数 user には変更はなく、新たに変更が反映されたオブジェクト newUser が返ってきます。
元の構造を維持するための ...user みたいなコードは一掃出来るのでどこに変化があるのかがわかりやすいです。

import produce from 'immer';

const user; // 変更前のユーザー
const additionalHoge = ['hoge', 'huga']; // 追加したいデータ

const newUser = produce(user, draftUser => {
  draftUser.detail.hoge = [...draftUser.detail.hoge, ...additionalHoge];
});

これくらいの構造のネストであれば、そのままjsで書いてもいいと思いますが、ネストが何重にもなればなるほど、immerの見やすさが顕著に出てくると思います。

使いどころとしてはreduxのreducerで使うような例が公式のreadmeにものってます。
他に使えそうと思ったところとして、react-apolloでreact-infinite-scrollerを用いた無限スクロールを行う際、元のデータにデータを追加するコードがスプレッド演算子だらけになるので、ここでも使えるなあと思いました。

react-apollのこういう感じのコードを綺麗に出来る。参考


          return {
            ...previousResult,
            search: {
              ...previousSearch,
              nodes: [...previousNodes, ...currentNodes],
              pageInfo: currentSearch.pageInfo,
            },
          };
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?