[React] Redux) useDispatch + useSelector

박세화·2023년 6월 21일
0

React JS

목록 보기
8/22

firebase.utils.js

export const getCategoriesAndDocuments = async () => {
  const collectionRef = collection(db, 'categories');
  const q = query(collectionRef);
  const querySnapShot = await getDocs(q);
  
  return querySnapShot.docs.map(docSnapshot => docSnapshot.data());
}

  • 태초에 firebase.utils.js가 있었다....
  • querySnapshot은 이렇게 생겼으며...docs를 하나씩 매핑해서 data()를 해주니 categoriesArray 가 생긴다.

shop.component.js

const Shop = () => {
  const dispatch = useDispatch();
  
  useEffect(()=>{
    const getCategoriesMap = async() => {
      const categoriesArray = await getCategoriesAndDocuments();
      dispatch(setCategories(categoriesArray));
    }
    getCategoriesMap();
  },[])

  • categoriesArray는 요래 생겼다.
  • useDispatch 훅을 이용해서 categoriesArray state의 상태 변경을 탐지한다.

categories.action.js

export const setCategories = (categoriesArray) =>
  createAction(CATEGOREIS_ACTION_TYPES.SET_CATEGORIES, categoriesArray);

category.reducer.js

import { CATEGOREIS_ACTION_TYPES } from './category.types'

export const CATEGORIES_INITIAL_STATE = {
  categories: [],
};

export const categoriesReducer = (
  state = CATEGORIES_INITIAL_STATE,
  action = {}
) => {
  const { type, payload } = action;

  switch (type) {
    case CATEGOREIS_ACTION_TYPES.SET_CATEGORIES:
      return { ...state, categories: payload };
    default:
      return state;
  }
};
  • Reducer function인 categoriesReducer가 현재 상태와 액션을 인자로 받고, type을 확인한 후 상태를 업데이트한다.

useSelector

공식문서) Allows you to extract data from the Redux store state for use in this component, using a selector function.

스토어의 상태값을 반환해주는 역할을 한다.

category.selector.js

export const selectCategoriesMap = (state) => {
  const categoriesMap = state.categories.categories.reduce((acc, category) => {
    const { title, items } = category;
    acc[title.toLowerCase()] = items;
    return acc;
  }, {});
  return categoriesMap;
};

  • selectCategoriesMap 안에서 console.log(state)를 찍어보면 위 사진처럼 나오기에(당연하다. categories라는 빈 배열 안에 categoriesArray가 들어갔기 때문에), 모든 카테고리와 그 안의 아이템들을 하나의 배열로 합치기 위해 reduce를 사용한다.

categories-preview.component.js

const CategoriesPreview = () => {
  const categoriesMap = useSelector(selectCategoriesMap);

category.component.js

const Category = () => {
  const { category } = useParams();
  const categoriesMap = useSelector(selectCategoriesMap)
  const [products, setProducts] = useState(categoriesMap[category]);

  • 그리하여 만들어진 categoriesMap을 컴포넌트에서 사용한다.

0개의 댓글