カスタムフックで Context をエクスポートしないようリファクタリングする

この記事では「React Context API を使う簡単な例」から「useContext フックで Consumer をリファクタリングする」にかけて作ってきたプログラムをリファクタリングします。

ここではカスタムフックを実装することで、Context も外部にエクスポートしないで済むようにします。

カスタムフックと言っても特別なコンポーネントがあるわけではありません。単に useContext を少しラップするだけです。

これまでFruitContext.jsとして作ったきたファイルは、fruit-hooks.jsという名前に変更します。

fruit-hooks.jsの中身は次のようにします。

import React, { createContext, useState, useContext } from 'react';
import { fruitData } from './fruit-data';

const FruitContext = createContext();

export const FruitProvider = ({ children }) => {
  const [fruits, setFruits] = useState(fruitData);
  const addFruit = (newFruit) => setFruits([...fruits, newFruit]);
  const removeFruit = (s) => setFruits(fruits.filter((fruit) => fruit !== s));

  return (
    <FruitContext.Provider value={{ fruits, addFruit, removeFruit }}>
      {children}
    </FruitContext.Provider>
  );
};

export const useFruits = () => useContext(FruitContext);

4 行目を変更して、FruitContets のエクスポートをやめます。

18 行目で useContext フックをラップして、 useFruits というフックを作りエクスポートします。

この部分が「カスタムフック」と呼んでいた部分です。たった一行の小さな変更です。しかしこれによって、Context も Consumer もエクスポートしなくて済むようになります。

カスタムフックを使う App.jsは次のようになります。

import React from 'react';
import { useFruits } from './fruit-hooks';
import './App.css';

function App() {
  const { fruits, addFruit, removeFruit } = useFruits();

  return (
    <>
      <h1>Fruits</h1>
      <div>
        <button onClick={() => addFruit(`Fruit ${fruits.length + 1}`)}>
          Add
        </button>
      </div>
      <ul>
        {fruits.map((fruit, i) => (
          <li key={i} onClick={() => removeFruit(fruit)}>
            {fruit}
          </li>
        ))}
      </ul>
    </>
  );
}

export default App;

2 行目で useFruitsカスタムフックを取り込んでいます。

6 行目で useFruits を呼ぶことで、Consumer で受け取れる value を受け取っています。

その他の部分は一緒です。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 React 入門