Open2

グローバルState管理

どるあがどるあが

バケツリレーで値を深いコンポーネントに渡すという大変なことを避けるためにグローバルstateを使用することができる

Javaでいうところのpublicでstaticなグローバルな変数といったところを実装することができる

providerで囲うことで中でstateを使える

App.js
  return (
    <UserProvider>
      <Router />
    </UserProvider>
  );
UserProvider.jsx
// Reactが絶対必要になるので忘れないように
// contextを使用する際にはcreateContextをインポート
import React, { createContext, useState } from "react";

// どのContextを呼び出しているか判別するために以下の一行が必要
export const UserContext = createContext({});
// UserContextを使うときのおきまり
// 何かを囲むときは以下のようにchildrenを使う
export const UserProvider = (props) => {
  const { children } = props;

  const [userInfo, setUserInfo] = useState(null);

  return (
    // 囲っている中でvalueの値が使える
    // 以下の描き方で、userInfoを使えるし、更新することも出来るようになる
    <UserContext.Provider value={{ userInfo, setUserInfo }}>
      {children}
    </UserContext.Provider>
  );
};
UserIconWithName.jsx
export const UserIconWithName = (props) => {
  const { image, name } = props;
  // useContextでどのUserContextを使用するのか指定する
  const { userInfo } = useContext(UserContext);
  const isAdmin = userInfo ? userInfo.isAdmin : false;

  return (
    <SContainer>
      <SImg height={160} width={120} src={image} alt={name} />
      <SName>{name}</SName>
      {isAdmin && <SEdit>編集</SEdit>}
    </SContainer>
  );
};
どるあがどるあが

Recoil

今まで勉強したのはなんだったのかというくらい便利

userState.js
import { atom } from "recoil";

export const userState = atom({
  // keyは一意。ファイル名とそろえるとベネ
  key: "userState",
  default: { isAdmin: false }
});

なんとたったこれだけでグローバルstateができてしまう。
しかも再レンダリングも最適化してくれるらしい。
なんだったんだ今までのものは。2022年では主流なのでガンガン使っていこう

とりあえず囲む

App.js
  return (
    <RecoilRoot>
      <UserProvider>
        <Router />
      </UserProvider>
    </RecoilRoot>
  );

値の参照には専用のuseRecoilValueをimport

// 値を参照するだけの時はuseRecoilValueを使用する
import { useRecoilValue } from "recoil";

~

  // useRecoilValueを使えば値の取得は以下のように定数で行える
  const userInfo = useRecoilValue(userState);

~

え、うせやんこれだけ??しかも定数で取り出せてるし簡単すぎる

値の更新には専用のuseSetRecoilStateを使用

Top.jsx
// 値の更新だけしたいときはuseSetRecoilStateを使用する
import { useSetRecoilState } from "recoil";

~

  // Recoilによるグローバルstate管理
  const setUserInfo = useSetRecoilState(userState);

  const onClickAdmin = () => {
    setUserInfo({ isAdmin: true });
    history.push("/users");
  };

再レンダリングも最適化してくれるそうな。これだけ知っておけばよかったのではと思う。ビビる。