3 minute read

学んだこと

Recoil とは

  • グローバルな state 管理ができるライブラリの 1 つ
  • これから主流になりそう。

実際に使ってみる

  • 使う前にnpm install recoilで recoil ライブラリをインストールする。
  • context 使っていた所を置き換えて実装した。

変更したコンポーネント一覧

  • App.jsx
    • RecoilRoot コンポーネントを追加
    • RecoilRoot コンポーネントにグローバルな state を定義している。
  • User.jsx
    • グローバルな state の set 関数と state 変数を呼び出し
  • UserIconWithName.jsx
    • グローバルな state の state 変数を呼び出し
  • Top.jsx
    • グローバルな state の set 関数を呼び出し
  • userState.js
    • グローバルな state の定義

App.jsx

  • context と同じように Router を囲むことで、グローバルな state を使えるようになる。
import './App.css';
import { Router } from './router/Router';
import { UserProvider } from './provider/UserProvider';
import { RecoilRoot } from 'recoil';
export default function App() {
  return (
    <RecoilRoot>
      <UserProvider>
        <Router />
      </UserProvider>
    </RecoilRoot>
  );
}

User.jsx

  • useRecoilState で state の変数と set 関数を呼び出す事ができる。
import styled from 'styled-components';
import { SearchInput } from '../molecules/SearchInput';
import { UserCard } from '../organisms/user/UserCard';
import { useLocation } from 'react-router-dom';
import { SecondaryButton } from '../atoms/button/SecondaryButton';
import { useContext } from 'react';
//import { UserContext } from '../../provider/UserProvider';
import { useRecoilState } from 'recoil';
import { userState } from '../../store/userState';

export const Users = () => {
  //const { userInfo, setUserInfo } = useContext(UserContext);
  const [userInfo, setUserInfo] = useRecoilState(userState);
  const onClickSwitch = () => setUserInfo({ isAdmin: !userInfo.isAdmin });

  return (
    <SContainer>
      <SUserArea>
        <h2>ユーザ一覧</h2>
        <SearchInput />
        <br />
        <SecondaryButton onClick={onClickSwitch}>切り替え</SecondaryButton>
        {users.map((user) => (
          <UserCard key={user.id} user={user} />
        ))}
      </SUserArea>
    </SContainer>
  );
};
const users = [...Array(10).keys()].map((val) => {
  return {
    id: val,
    name: `あああ${val}`,
    image:
      'https://images.unsplash.com/photo-1598133894008-61f7fdb8cc3a?q=80&w=988&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
    email: '12345@example.com',
    phone: '000-0000-0000',
    company: {
      name: 'テスト株式会社',
    },
    website: 'https://google.com',
  };
});

const SContainer = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 24px;
`;

const SUserArea = styled.div`
  padding-top: 40px;
  width: 100%;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  grid-gap: 20px;
`;

UserIconWithName.jsx

import styled from 'styled-components';
import { SearchInput } from '../molecules/SearchInput';
import { UserCard } from '../organisms/user/UserCard';
import { useLocation } from 'react-router-dom';
import { SecondaryButton } from '../atoms/button/SecondaryButton';
import { useContext } from 'react';
//import { UserContext } from '../../provider/UserProvider';
import { useRecoilState } from 'recoil';
import { userState } from '../../store/userState';

export const Users = () => {
  //const { userInfo, setUserInfo } = useContext(UserContext);
  const [userInfo, setUserInfo] = useRecoilState(userState);
  const onClickSwitch = () => setUserInfo({ isAdmin: !userInfo.isAdmin });

  return (
    <SContainer>
      <SUserArea>
        <h2>ユーザ一覧</h2>
        <SearchInput />
        <br />
        <SecondaryButton onClick={onClickSwitch}>切り替え</SecondaryButton>
        {users.map((user) => (
          <UserCard key={user.id} user={user} />
        ))}
      </SUserArea>
    </SContainer>
  );
};
const users = [...Array(10).keys()].map((val) => {
  return {
    id: val,
    name: `あああ${val}`,
    image:
      'https://images.unsplash.com/photo-1598133894008-61f7fdb8cc3a?q=80&w=988&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
    email: '12345@example.com',
    phone: '000-0000-0000',
    company: {
      name: 'テスト株式会社',
    },
    website: 'https://google.com',
  };
});

const SContainer = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 24px;
`;

const SUserArea = styled.div`
  padding-top: 40px;
  width: 100%;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  grid-gap: 20px;
`;

Top.jsx

  • set 関数だけ呼び出したいときは、useSetRecoilState を使用する。
import styled from 'styled-components';
import { SecondaryButton } from '../atoms/button/SecondaryButton';
import { useHistory } from 'react-router-dom';
import { useContext } from 'react';
import { UserContext } from '../../provider/UserProvider';
import { useSetRecoilState } from 'recoil';
import { userState } from '../../store/userState';

export const Top = () => {
  const history = useHistory();
  //const { setUserInfo } = useContext(UserContext);
  const setUserInfo = useSetRecoilState(userState);
  const onClickAdmin = () => {
    setUserInfo({ isAdmin: true });
    history.push('/users');
  };
  const onClickGeneral = () => {
    setUserInfo({ isAdmin: false });
    history.push('/users');
  };

  return (
    <SContainer>
      <h2>TOPページです</h2>
      <SecondaryButton onClick={onClickAdmin}>管理者</SecondaryButton>
      <SecondaryButton onClick={onClickGeneral}>一般ユーザ</SecondaryButton>
    </SContainer>
  );
};

const SContainer = styled.div`
text-align: center`;

userState.js

  • atom で state の情報を設定する。
    • key
      • state を参照するための名前
    • default
      • state の初期値
import { atom } from 'recoil';

export const userState = atom({
  key: 'userState',
  default: { isAdmin: false },
});

JSONPlaceholder とは

  • フェイクデータを返す RESTAPI
    • フロントエンド開発で、バックエンドがまだ完成していないときに便利。
    • データの取得や投稿などの HTTP リクエストを試す事ができる。

実際に使ってみた

  • 使う前に、npm install axiosで axios をインストールしておく。
  • axios.get(URL).then((取得したデータ)=>(取得した後の処理)).catch((取得失敗時のエラー情報)=>(取得失敗時のエラー処理))
import './App.css';
import axios from 'axios';

export default function App() {
  const onClickUsers = () => {
    axios
      // user全部の情報を取得する。
      .get('https://jsonplaceholder.typicode.com/users')
      // 取得成功した場合の処理
      .then((res) => {
        console.log(res.data);
      })
      // 取得失敗したときの処理
      .catch((err) => console.log(err));
  };
  const onClickUser1 = () => {
    axios
      // ユーザ=1のデータを取得する。
      .get('https://jsonplaceholder.typicode.com/users/1')
      // 取得成功した場合の処理
      .then((res) => {
        console.log(res.data);
      })
      // 取得失敗したときの処理
      .catch((err) => console.log(err));
  };
  return (
    <div className="App">
      <button onClick={onClickUsers}>users</button>
      <button onClick={onClickUser1}>user1</button>
    </div>
  );
}

Tags:

Updated: