Reduxでのセレクター取得
アプリケーションから余分なコードを取り除き、 データをカプセル化することは、時に非常に役立ちます。
商品アプリケーションを開いてみましょう。 アプリケーションのいくつかの場所で、 セレクターを使って商品のスライスを取得し、 それに対して何らかの操作を行っていることに注意してください。
次に、ファイル productsSlice.js を開き、
ファイルの最後までスクロールして数行コードを追加します。
そこでは2つのセレクター関数を記述してエクスポートします。
1つ目の関数はすべての商品を取得するためのものです:
export const selectAllProducts = (state) => state.products.products
その後に、idによる単一商品の取得のための2つ目の関数を追加します:
export const selectProductById = (state, productId) =>
state.products.products.find((product) => product.id === productId)
当然、state.products.products のような
ネスト構造について疑問に思うかもしれません。
答えは簡単です。前回のレッスンでスライスの構造を変更し、
商品がスライスの独立したプロパティ products 内に
配列として格納されるようになったからです。
これは商品スライス state.products 内にあります
(ここでの state は、
すべてのReduxスライスを含むルート状態オブジェクトであることを思い出してください)。
このように、セレクター関数のコードを
アプリケーション内の1箇所に移動したので、
それを使用していた場所で適切な変更を行う必要があります。
ファイル ProductsList.jsx から始めましょう。
ここではすべての商品を取得する必要があるため、
selectAllProducts をインポートします:
import { selectAllProducts } from './productsSlice'
そして、関数 ProductsList のコードの先頭で、以下の部分を置き換えます:
const products = useSelector((state) => state.products)
以下の行に置き換えます:
const products = useSelector(selectAllProducts)
次に、ファイル ProductPage.jsx に移動します。
ここではidによる商品が必要でした。
以下の行を置き換えます(インポートを忘れずに):
const product = useSelector((state) =>
state.products.find((product) => product.id === productId)
)
以下のように置き換えます:
const product = useSelector((state) => selectProductById(state, productId))
ファイル EditProductForm.jsx でも同様の置き換えを自分で行ってください。
ここでもidによる商品が必要です。
このような最適化は、あくまで開発者の利便性のためのものであり、 必要かつ便利だと感じたときに実施すればよいということを覚えておいてください。 今回の例で考えてみると、もしセレクター関数のコードを さまざまな場所で毎回書いていたら、 後で状態の構造を変更した際に、 すべてのコンポーネントで修正しなければならなかったでしょう。
学生管理アプリケーションを開いてください。
その中のファイル studentsSlice.js を開きます。
ファイルの最後に、レッスンで示したように、
すべての学生を取得するための selectAllStudents と、
idによる単一学生を取得するための selectStudentById の
2つのセレクターを記述してエクスポートしてください。
次に、selectAllStudents と selectStudentById を
ファイル StudentsList.jsx、StudentPage.jsx、
EditStudentForm.jsx にインポートし、
これらのファイルでレッスンで示したような対応する変更を行ってください。