React

React-Redux 저장소(Store) 생성하기

학습했던 내용을 정리하기 위해 작성된 글이며 다소 부정확한 내용이 포함될 수 있음을 양해바랍니다.

이미 게시된 글이라도 복습하는 과정에서 내용이 보완 또는 수정될 수 있습니다.

 

//store.js

import { createStore } from 'redux';

import reducer from './reducer';

const store = createStore(reducer);

export default store;

리덕스의 store는 상태를 갖는 저장소이다. 그리고 단 하나의 리듀서라는 것을 갖는다. 리덕스의 createStore API를 통해 store를 생성하는데 그 첫번째 파라미터로 리듀서를 전달한다. 저장소(store)의 파일 이름은 store.js 로 생성해준다.

//reducer.js

const initialState = {
  categories: [],
  restaurants: [],
};

export default function reducer(state = initialState, action) {
  if (action.type === 'updateRegions') {
    const { regions } = action.payload;
    return {
      ...state,
      regions,
    };
  }

  if (action.type === 'updateCategories') {
    const { categories } = action.payload;
    return {
      ...state,
      categories,
    };
  return state;
}

리듀서는 기본적으로 상태와 액션을 받는다. 여기서 받는 상태는 누적된 값, 즉 바로 이전 상태를 의미하며 전달되는 액션에 따라 이전 상태를 변경하여 리턴한다. reducer.js로 분리시켜주는 것이 좋다.

 

//actions.js

export function updateRegions(regions) {
  return {
    type: 'updateRegions',
    payload: {
      regions,
    },
  };
}

export function updateCategories(categories) {
  return {
    type: 'updateCategories',
    payload: {
      categories,
    },
  };
}

action creator는 액션을 리턴한다. 액션은 일종의 객체와 같다. 액션은 타입을 갖는데 이는 각각의 식별자라고 할 수 있다. 그리고 payload를 포함할 수 있는데, payload에는 상태 변경에 필요한 다른 객체가 포함된다. 액션 또한 다른 파일로 분리시켜 주는 것이 좋다. 

//App.jsx

import { useEffect } from 'react';

import { useDispatch } from 'react-redux';

import { updateRegions, updateCategories } from '../actions';

export default function App() {
	const dispatch = useDispatch();
	
	useEffect(() => {
		dispatch(updateRegions());
    dispatch(updateCategories());
  }, []);

	return (
    <div>
      ...
    </div>
  );
}

Flux에서 dispatcher는 데이터 플로우를 관리하는 중재자의 역할을 수행하는데, 이를 통해 스토어에 접근할 수 있다. 하지만 리덕스는 dispatcher를 갖고 있지 않다. 다만, 리듀서에 액션을 전달하는 dispatch 메서드를 제공한다. 위 코드와 같이 dispatch 메서드에 원하는 액션을 포함시켜 전달해주면 된다. 리듀서는 각 액션에 따라 상태를 변경하여 리턴하고 이렇게 변경된 상태는 스토어에 의해 view에 통지된다.

//index.jsx

import ReactDOM from 'react-dom';

import { Provider } from 'react-redux';

import App from './App';

import store from './store';

ReactDOM.render(
  (
    <Provider store={store}>
      <App />
    </Provider>
  ),
  document.getElementById('app'),
);

컴포넌트가 스토어에 접근할 수 있도록 루트 파일에서 내부 컴포넌트를 감싸준다.

  • 리덕스는 단 방향 데이터 흐름을 구현한다. 나열하자면,
    • state는 App의 데이터를 서술한다. 그리고 UI는 그 상태에 기반하여 렌더링된다.
    • UI는 액션을 디스패치한다.
    • (예시. DOM 이벤트가 발생하면 디스패치 메서드를 통해 특정 액션을 리듀서에 전달한다)
    • store는 리듀서를 실행하고, 리듀서는 전달된 액션에 따라 state를 변경한다.
    • store는 state의 변경을 view(즉, UI)에 알린다.
    • UI는 새로운 state에 기반하여 다시 렌더링 된다.

'React' 카테고리의 다른 글

React defaultProps  (0) 2022.01.24
의존성 주입이란 무엇인가?  (0) 2021.09.19
React-Thunk를 활용한 비동기적 상태관리  (0) 2021.09.10
Flux와 MVC의 차이에 대해 공부하기  (0) 2021.08.30