Reactのリフトアップを用いて、コンポーネント間で状態管理を共有する
現在個人開発中のアプリで、ChatGPT-APIとの送受信中にボタンのdisabled属性を切り替える必要が出てきた。
属性を切り替えるにはuseStateを使い、状態管理を親コンポーネントで行う。
例えば、以下のようなコンポーネントがあると仮定する。
ChildComponent
const Child = () => {
const sendData = async () => {
try {
const response = await fetch("/api/connectChatGPT_API", {
method: "POST",
// 省略
headers: {
const data = await response.json();
const responseText = data.responseText;
} catch (error) {
console.error("error occurred\n", error)
}
}
return <button disabled={}>button</button>;
};
ParentCompenent
const Parent = () => {
return <Child />
}
ここから、親コンポーネント、子コンポーネントを以下のように修正する。
ChildComponent
const Child = () => {
const sendData = async ({setIsDisabled, getIsDisabled}) => {
try {
setIsDisabled(true);
const response = await fetch("/api/connectChatGPT_API", {
method: "POST",
// 省略
headers: {
const data = await response.json();
const responseText = data.responseText;
// APIからのレスポンスを確認して、Childコンポーネントのを元に戻す
if (responseText) {
setIsDisabled(false);
}
} catch (error) {
console.error("error occurred\n", error)
}
}
return <button disabled={getIsDisabled}>button</button>;
};
ParentCompenent
const Parent = () => {
const [isDisabled, setIsDisabled] = useState<boolean>(false);
return (
<Child
setIsDisabled={setIsDisabled}
getIsDisabled={isDisabled}
/>
}
1.APIへの送信が行われると、Childコンポーネントの`setIsDIsabled(true)`になり、データはParentコンポーネントに渡される。
2.渡された`true`というデータを、Parentコンポーネント内でuseStateを用いて更新関数により管理する。
3.Parentコンポーネントから、trueが設定されている状態関数isDisabledをChildコンポーネントの`getIsDisabled`パラメータに渡す。
4.Childコンポーネントは、getIsDisabledパラメータをbuttonタグ内に記述しているdisabledプロパティに設置する。
5.APIからの通信が正常に終わり返信があれば、try{}内のスコープにてsetIsDIsabled(false)と記述する。
6.`false`は、setIsDisabledを通じてParentコンポーネントに渡され、更新関数が実行される。
7.先程と同様に、getIsDisabledパラメータをbuttonタグ内に記述しているdisabledプロパティに設置する。
要点だけを記述したが、リフトアップを適切に使用することで状態管理をより簡易に出来るようになった。
このコンポーネント間を経由する状態管理を、より柔軟に行える`createContext`という仕組みもあるが、これは折を見て学んでいこうと思う。