Uzyskiwanie selektorów w Redux

Czasami bardzo przydatne jest pozbycie się zbędnego kodu w aplikacji, a także enkapsulacja danych.

Otwórzmy naszą aplikację z produktami. Zwróć uwagę, że w kilku miejscach aplikacji my, używając selektorów, pobieramy slice z produktami, aby wykonać z nim jakieś działania.

A teraz otworzymy nasz productsSlice.js, zejdziemy na sam koniec pliku i dodamy kilka linijek kodu, w którym napiszemy dwa selektory i je wyeksportujemy. Jedna funkcja u nas będzie do uzyskiwania wszystkich produktów:

products/productsSlice.jsexport const selectAllProducts = (state) => state.products.products

A po nim druga - do uzyskiwania jednego produktu po id:

products/productsSlice.jsexport const selectProductById = (state, productId) =>
  state.products.products.find((product) => product.id === productId)

Oczywiście może pojawić się słuszne pytanie - skąd u nas taki wynalazek: state.products.products? Odpowiedź jest prosta, przecież na poprzedniej lekcji zmieniliśmy strukturę slice'a i teraz nasze produkty będą znajdować się w postaci tablicy w osobnej właściwości products slice'a produktów state.products (pamiętajcie, że tutaj state - to jest główny obiekt stanu Redux, który zawiera wszystkie slice'y).

W ten sposób po prostu przenieśliśmy kod dla funkcji-selektorów w jedno miejsce w aplikacji i teraz musimy wprowadzić odpowiednie zmiany tam, gdzie je używaliśmy. Zacznijmy od pliku ProductsList.jsx. Zaimportujmy do niego selectAllProducts, ponieważ tutaj nam trzeba będzie uzyskać wszystkie produkty:

products/ProductsList.jsximport { selectAllProducts } from './productsSlice'

I na początku kodu funkcji ProductsList, zamieńmy:

products/ProductsList.jsxconst products = useSelector((state) => state.products)

Na linijkę:

products/ProductsList.jsxconst products = useSelector(selectAllProducts)

A teraz przejdźmy do pliku ProductPage.jsx. Tutaj nam potrzebny był produkt po id. Zróbmy zamianę linii (nie zapomnijcie o imporcie):

products/ProductPage.jsxconst product = useSelector((state) =>
  state.products.find((product) => product.id === productId)
)

Na:

products/ProductPage.jsxconst product = useSelector((state) => selectProductById(state, productId))

Zróbcie podobną zamianę samodzielnie w pliku EditProductForm.jsx. Tutaj nam również potrzebny jest produkt po id.

Pamiętajcie, że taka optymalizacja jest tylko dla waszej wygody i możecie ją zrobić wtedy, kiedy uznacie za potrzebną i wygodną. A na naszym przykładzie wyobraźcie sobie, że my by pisali kod funkcji-selektora za każdym razem w różnych miejscach, a potem by zmienili strukturę stanu, i trzeba by go wtedy poprawiać we wszystkich komponentach.

Задание 1

Otwórz twoją aplikację ze studentami. Otwórz w niej plik studentsSlice.js. Na samym dole pliku napisz i wyeksportuj, jak pokazano w lekcji, dwa selektory do uzyskiwania wszystkich studentów selectAllStudents i do uzyskiwania jednego studenta po id selectStudentById.

Задание 2

Teraz zaimportuj selectAllStudents i selectStudentById do plików StudentsList.jsx, StudentPage.jsx i EditStudentForm.jsx, wprowadź w tych plikach odpowiednie zmiany, jak pokazano w lekcji.