React の dispatch を分割して部分的にステートを書き換える
ステートに object を入れると dispatch しにくい
例として、<Main />
、<Article />
、<Section />
の階層構造を持つ React アプリケーションを考えます。
・<Main />
・<Article />
・<Section />
React 以外のステート管理ライブラリを使わず、useContext
によるグローバルステートも使わない場合、以下のようにステート管理を書けます。
import { memo, useEffect, useState } from "react";
const Main = memo(() => {
// useReducer でも可。
const [main, dispatchMain] = useState({
article: {
section: {
content: "initial section content"
// 他のプロパティ
}
// 他のプロパティ
}
// 他のプロパティ
});
return <Article article={main.article} dispatchMain={dispatchMain} />;
});
const Article = memo(({ article, dispatchMain }) => (
<Section section={article.section} dispatchMain={dispatchMain} />
));
const Section = memo(({ section, dispatchMain }) => {
useEffect(() => {
setTimeout(
() =>
dispatchMain((prevMain) => ({
...prevMain,
article: {
...prevMain.article,
section: {
...prevMain.article.section,
content: "Section content is updated."
}
}
})),
3000
);
}, [dispatchMain]);
return <>{section.content}</>;
});
export default Main;
dispatchMain
を子コンポーネントに渡すことで、子コンポーネントからステートを書き換えられるようになりました。この例では簡単に useState
を使用していますが、代わりに useReducer を使って reducer
関数を自力が書けば、ステートの変化を <Main />
からでも制御できます。
しかし…… main.article.section.content
を書き換えるために dispatchMain
を使うの、冗長ではないでしょうか?
dispatchMain((prevMain) => ({
...prevMain,
article: {
...prevMain.article,
section: {
...prevMain.article.section,
// ここを書き換えたいだけなのに、冗長な dispatch を書いている。
content: "Section content is updated."
}
}
}));
そこで、dispatchMain
から dispatchArticle
を作り、さらに dispatchArticle
から dispatchSection
を作ります。
dispatch を分割して部分的にステートを書き換える
以下のようにして、dispatchArticle
と dispatchSection
を作れます。
const dispatchArticle = useCallback(
(action) =>
dispatchMain((prevMain) => ({
...prevMain,
article:
typeof action === "function" ? action(prevMain.article) : action
})),
[]
);
const dispatchSection = useCallback(
(action) =>
dispatchArticle((prevArticle) => ({
...prevArticle,
section:
typeof action === "function" ? action(prevArticle.section) : action
})),
[dispatchArticle]
);
main.article.section.content
を書き換えるコードは、以下のようにすっきり書けます。
dispatchSection((prevSection) => ({
...prevSection,
// すっきりと書ける。
content: "Section content is updated."
}));
「dispatch を分割するパターン」が広まってほしい
この「dispatch を分割するパターン」、私は好きなのですが、インターネット上には全く事例がない。素直にステート管理ライブラリを使うべきなのか、それとも React だけでシンプルにステート管理するべきなのか……。useContext
でグローバルステートを作ると、レンダリングパフォーマンスの管理が難しいしな……。
「dispatch を分割するパターン」が認知されると、メリット・デメリットも見えてきて、うれしいですね。
Author And Source
この問題について(React の dispatch を分割して部分的にステートを書き換える), 我々は、より多くの情報をここで見つけました https://qiita.com/hata6502/items/dc78fd597e8155dbfbcc著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .