はじめに
どうもこんにちは!僕は現在1ヵ月本気の技術力向上を目指している現役高校生1年生(@shunii )です!とあるUdemyの講座にしたがってReactのアプリを開発していたところ躓いたところがあったので共有します。
対象読者
今回は下記の講座を受けている前提で話を進めさせていただきます。
問題
selectedUser(選択したユーザーの名前)が表示されない!
筆者の状況
- ユーザーカードをクリックした際にidを取得することはできている
- console.logで確認するもののselectedUserはundefinedである
- usersをconsole.logで確認すると、空配列([ ])になっている
- たまにselectedUserが表示される
export const UserManagement: FC = memo(() => {
const { getUsers, users, loading } = useAllUsers();
const { isOpen, onClose, onOpen } = useDisclosure();
const { onSelectUsers, selectedUser } = useSelectUsers();
const { loginUser } = useLoginUser();
console.log(selectedUser); //ここ
const onClickUser = useCallback((id: number) => {
onSelectUsers({ id, users, onOpen });
}, []);
useEffect(() => {
getUsers();
}, []);
return //...以下省略
});
解決策
結論
onClickUserでuseCallbackの第2引数に users を追加する
原因としては、usersを設定していない(要するにgetUsersが完了する前の)段階でonClickUser関数を生成していたので、usersが空配列(初期値)となってしまっていました。それに加え、useCallbackの第2引数の配列を空にしていたため、usersが設定されても新しく関数が再生成されることはありません。
検証
最初に示した通り、なぜか selectedUser がたまに表示されるという現象が起こったのでそれを解明しておきたいと思います。
以下のようにconsole.logを仕込んでみます。
export const UserManagement: FC = memo(() => {
const { getUsers, users, loading } = useAllUsers();
const { isOpen, onClose, onOpen } = useDisclosure();
const { onSelectUsers, selectedUser } = useSelectUsers();
const { loginUser } = useLoginUser();
console.log("============ aaaaaaa ============"); //追加
console.log(selectedUser); //ここ
const onClickUser = useCallback((id: number) => {
onSelectUsers({ id, users, onOpen });
}, []);
useEffect(() => {
getUsers();
}, []);
return //...以下省略
});
以下のように検証します
console.logの中身だけを適当に変更してみます。すると、selectedUserがしっかりととれていることがわかります。
なぜたまに表示されるのか
たまに表示されたのは、
親コンポーネントで再レンダリングが走った
ということが原因であるとわかりました。
さきほど検証でconsole.logの中身を変更するだけでselectedUserを取り出すことに成功しました。
これはUserManagementコンポーネントで変更(console.logの)が検出されたために再レンダリングが走り、それによってその配下にあるonClickUser関数が再生成されたからです。再生成時にはusersが既に設定済み(ある程度時間がたっているから)なのでうまく実行できます。
終わりに
今回の問題は自分だけで解決することができませんでしたが、Reactの再レンダリングの条件の復習などを兼ねることができたためよかったです!
About Me
- X(Twitter)