ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 4. Redux로 전역 상태 관리하기
    React 2022. 5. 2. 16:37
    목차

    1. redux 기본 설정
    2. redux 사용하기 : createStore, Provider, useSelector, useDispatch

     

    1. redux 기본설정

    npm i redux
    npm i react-redux // 리액트 외부 라이브러리인 redux를 리액트와 연결해주기 위해서
    npm i react-devtools-extension // 개발단계에서 크롬에서 리덕스 개발자도구 사용하기 위해서

    필요한 파일

    1. useStore.jsx

    2. reducer.js (보통 rootReducer와 +@로 나눠서 씀)

    3. index.js (최상단에 Store 컴포넌트 삽입)

     

     

     

    2. redux 사용하기

    1. createStore를 사용하여 전역상태관리를 할 수 있는 store 객체를 생성함

    • createStore의 첫번째 인자 : state를 바꿔주는 reducer함수
    • createStore의 두번째 인자 : 초기 state 값. 위 코드에서는 사용하지 않았고 초기state는 reducer함수에서 정의해줌.
    • createStore의 세번째 인자 : Enhancer. 미들웨어나 서드파티 확장도구 등을 넣음. 위 코드에서는 브라우저에서 redux 개발자도구를 사용할 수 있게 하는 composeWithDevTools()를 입력해주었다.

     

    2. Store 컴포넌트 생성

    redux-react 설치 시에 사용 가능한 Provider를 사용하여 최상단 컴포넌트를 감싸주어 전역상태객체 store를 내부에서 사용할 수 있게 해주었다.

     

    useStore.jsx

    import { createStore } from 'redux'
    import { Provider } from 'react-redux'
    import { composeWithDevTools } from 'redux-devtools-extension'
    import rootReducer from '../reducers'
    
    const store = createStore(rootReducer, composeWithDevTools())
    
    const Store = ({ children }) => {
        return (
            <Provider store={store}>
                {children}
            </Provider>
        )
    }
    
    export default Store
    
    // 기존에 useContext로 store만들었을 때는 
    // <Store.Provider value={initialState}>{children}<Store.Provider>
    // 이렇게 썼던걸 리덕스로는 react-redux에서 제공하는 Provider를 사용하면 됨

     

     

     

    3. 최상단 컴포넌트인 App.js를 감싸주기 위해 index.js에 위에서 만든 Store 컴포넌트를 불러와 사용.

     

    - index.js

    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
        <React.StrictMode>
            <Store>
                <App />
            </Store>
        </React.StrictMode>
    );

     

    4. reducer.js 작성

     

    state를 변경해주는 함수 reducer를 작성해준다.

    <reducer.js 파일에서 해줄 것>

    1. 초기 state 정의해주기
    2. reducer에서 사용할 action을 변수로 빼서 정의 (오타를 방지해준다!)
    3. 내부 컴포넌트에서 dispatch 사용시 위에서 변수로 만든 action을 쉽게 사용할 수 있도록 함수로 만들어 export해줌.
    4. Reducer 함수 만들기

    - reducer.js

    const initialState = {
        number: 0
    }
    const UP = 'COUNTER/UP'
    const DOWN = 'COUNTER/DOWN'
    
    export const up = () => ({ type: UP })
    export const down = () => ({ type: DOWN })
    
    const rootReducer = (state = initialState, action) => {
        switch (action.type) {
            case UP:
                return {
                    ...state,
                    number: state.number + 1
                }
            case DOWN:
                return {
                    ...state,
                    number: state.number - 1
                }
            default:
                return state
        }
    }
    
    export default rootReducer

     

     

     

    5. 컴포넌트에서 state와 dispatch 가져와서 사용하기

    Counter 컴포넌트에서 store에 있는 전역상태를 가져오고 상태를 변경해보자

    1. react-redux로 상태값 가지고 오는 메소드 useSelector, 디스패치 함수 가지고오는 메소드 useDispatch  import하기
    2. reducer.js 파일에서 만들어둔 action 함수 up(), down() 가져오기
    3. onClick 함수에서 dispatch 실행하기

     

    - Counter.jsx

    import { useSelector, useDispatch } from "react-redux"; // 전역상태 Store에 접근가능한 메소드
    import { up, down } from "../../reducers";
    
    const Counter = () => {
        const dispatch = useDispatch()
        const counter = useSelector(state => state) 
        // 인자값으로 콜백함수 : 콜백함수의 인자값 state = store 내의 모든 state
        // store내에 counter/board/user... 여러가지 state가 있을 때 컴포넌트에서 필요한 부분만 가져올 수 있도록 콜백함수 사용
        // useSelect(state => state.counter)
        // useSelect(state => state.board)
        // 이런 식으로..
    
    
        const onUp = () => {
            dispatch(up())
        }
    
        const onDown = () => {
            dispatch(down())
        }
    
        return (
            <>
                <h3> Counter : {counter.number} </h3>
                <button onClick={onUp}>+</button>
                <button onClick={onDown}>-</button>
            </>
        )
    }
    
    export default Counter;

     

Designed by Tistory.