[React] useStateValue()의 리턴값이 undefined

wisdom·2022년 5월 22일
0

Troubleshooting

발생한 문제

  • 아래 코드를 추가하면 에러가 발생한다.
import {useStateValue} from "../components/StateProvider";

const [{basket}, dispatch] = useStateValue();

해결 및 시도 방법

에러 메시지 확인

  • 에러 메시지에 있는 공식 문서 확인

    • https://reactjs.org/docs/error-boundaries.html
    • Error Boundaries
      • 에러를 처리하는 방식이고, 시스템 장애 화면을 따로 정의하여 보여주고 싶을 때, 아래 ErrorBoundary 컴포넌트를 이용할 수 있다 라는 건데 지금 이슈를 해결할 수 있는 방법은 아니라고 판단함.
  • 브라우저 콘솔탭 다시 확인
    - 브라우저 콘솔탭에서 에러가 나는 부분을 따라가보니 useStateValue(); 의 리턴값이 undefined 이어서 생기는 문제라고 판단.

왜 useStateValue의 값이 undefined 일까?

StateProvider.js

import React, {createContext, useContext, useReducer} from "react";


export const StateContext = createContext();

export const StateProvider = ({reducer, initialState, children}) => (
    <StateContext.Provider value={useReducer(reducer, initialState)}>
        {children}
    </StateContext.Provider>
);

export const useStateValue = () => useContext(StateContext);

Reducer.js

export const initialState = {
    basket: [],
}


const reducer = (state, action) => {
    switch (action.type) {
        case 'ADD_TO_BASKET':
            return {
                ...state,
                basket: [...state.basket, action.item]
            };
        case 'REMOVE_FROM_BASKET':
            const index = state.basket.findIndex(
                (basketItem) => basketItem.id === action.id
            );
            let newBasket = [...state.basket];

            if (index >= 0) {
                newBasket.splice(index, 1);
            } else {
                console.warn(
                    ' (id: ' +
                    action.id +
                    ')이 장바구니에 존재하지 않습니다 '
                )
            }

            return {
                ...state,
                basket: newBasket
            };
        default:
            return state;
    }
}

export default reducer;
  • useStateValue() 와 관련된 파일은 에러도 없고 코드상으로 직접적인 문제가 없어보였다. 그런데 stateProvider 변수를 만든 목적이 있기 때문에 당연히 어딘가에서 쓰고 있어야 하는데 한 번도 쓰지 않아서 툴에서 회색빛으로 표시해주는 걸 뒤늦게 발견함.
  • useReducer로 만든 state와 dispatch를 useContext를 이용해 하위 컴포넌트들이 사용할 수 있게끔 코드를 다 만들어놨는데 index.js 파일에서 < App/ > 을 < StateContext />로 감싸주지 않아서 발생하는 에러였다.

Before

   <BrowserRouter>
       <App/>
    </BrowserRouter>

After

  <BrowserRouter>
    <StateProvider initialState={initialState} reducer={reducer} >
        <App/>
    </StateProvider>
  </BrowserRouter>

회고

  • 콘솔탭에 있는 에러를 잘 읽는 게 정말 중요하다.
  • 다음에 여유가 생기면 아래 공식문서를 좀 제대로 공부해야겠다. 라고 느꼈다. 이유는 크롬 개발자 도구를 잘 다루고 디버깅을 잘 하면 해당 에러를 해결하는데 시간이 훨씬 줄어들지 않았을까? 라고 생각하기 때문이다. 지금은 복잡하지 않은 코드이지만 코드가 좀 더 복잡해지만 디버깅 실력은 필수라고 생각한다.
profile
문제를 정의하고, 문제를 해결하는

0개의 댓글