![Reactでオブジェクトの場合はuseStateよりuseImmerのほうが便利](https://iwb.jp/wp-content/uploads/2024/05/react-useimmer-useful-than-use-state-for-nest-objects.png)
useImmerとは
useImmerはReactのフックであり、Immerライブラリを使用して、状態の不変性を簡単に管理できます。
Reactの状態管理において、オブジェクトのネストされたプロパティを更新するのは煩雑になりがちです。
しかし、Immerを使うことで、変更可能な操作のように見えるコードを書いても、実際には不変の状態が保たれます。
例えば以下のようなオブジェクトの場合、値を変更する際にスプレッド構文(...person)を多様することになり、コードの可読性が悪くなります。
TSX
import { useState, ChangeEvent } from 'react'
export default function App() {
const [person, setPerson] = useState({
name: 'Yamada',
work: {
company: 'NTT',
}
})
function handleNameChange(e: ChangeEvent<HTMLInputElement>) {
setPerson({
...person,
name: e.target.value,
})
}
function handleCompanyChange(e: ChangeEvent<HTMLInputElement>) {
setPerson({
...person,
work: {
...person.work,
company: e.target.value,
}
})
}
return (
<>
<label>
Name:
<input
value={person.name}
onChange={handleNameChange}
/>
</label>
<br />
<label>
Company:
<input
value={person.work.company}
onChange={handleCompanyChange}
/>
</label>
<hr />
<p>
{person.name} works for {person.work.company}
</p>
</>
)
}
useImmerを使った場合
useStateの代わりにuseImmerを使うと、スプレッド構文(…person)を使わないシンプルなコードになります。
まず、useImmerを以下のコマンドでインストールします。
ShellScript
npm i -D use-immer
次にuseImmerをimportして、useStateをuseImmerに書き換えます。
TSX
import { ChangeEvent } from 'react'
import { useImmer } from 'use-immer'
export default function App() {
const [person, setPerson] = useImmer({
name: 'Yamada',
work: {
company: 'NTT',
}
})
// 中略
}
最後にhandleNameChangeなどのChangeEventをスプレッド構文を使わない以下の形に変更します。
TSX
import { ChangeEvent } from 'react'
import { useImmer } from 'use-immer'
export default function App() {
const [person, setPerson] = useImmer({
name: 'Yamada',
work: {
company: 'NTT',
}
})
function handleNameChange(e: ChangeEvent<HTMLInputElement>) {
setPerson(draft => {
draft.name = e.target.value
})
}
function handleCompanyChange(e: ChangeEvent<HTMLInputElement>) {
setPerson(draft => {
draft.work.company = e.target.value
})
}
return (
<>
<label>
Name:
<input
value={person.name}
onChange={handleNameChange}
/>
</label>
<br />
<label>
Company:
<input
value={person.work.company}
onChange={handleCompanyChange}
/>
</label>
<hr />
<p>
{person.name} works for {person.work.company}
</p>
</>
)
}
以上の変更だけで、スプレッド構文を使わないシンプルなコードに変更できます。