Redux

jinabbb·2022년 4월 14일
0

자바스크립트 애플리케이션에서 상태를 효율적으로 관리할 수 있게 도와주는 라이브러리

주요개념

Action

상태 변화를 일으킬 때 참조하는 객체

{
  type: "ADD_TODO",
  payload: {
    id: 0,
    text: "redux"
  }
}

type으로 액션을 구분하고 payload의 값으로 State를 업데이트 한다.

Action Creator

액션객체를 만드는 헬퍼함수

const createAction = (type, payload) => ({ type, payload });

Reducer

이전 상태와 액션을 입력받아 변화를 일으키는 함수.

반드시 순수함수여야 한다.(리턴 값은 파라미터 값에만 의존하며 언제나 같은 결과를 출력)

State의 변화는 Reducer에서만 일어나야한다

Store

컴포넌트 외부에 있는 State 저장소

Dispatch

리듀서 함수를 호출하여 액션에 맞게 상태를 변화시킨다.

리덕스 상태 변화의 흐름

참고)) 리액트가 없이 쓰는 리덕스

https://velopert.com/3528

실제 내 프로젝트에 적용하기

스토어 만들기

src/store/store.js

import { compose, createStore, applyMiddleware } from 'redux';
import logger from 'redux-logger';

import { rootReducer } from './root-reducer';

const middleWare = [logger];

const composedEnhancers=compose(applyMiddleware(...middleWare));

export const store = createStore(rootReducer,undefined,composedEnhancers);

리듀서들을 컴바인한 rootReducer와 middleWare들을 compose해서 만든다

루트 리듀서 만들기

src/store/root-reducer.js

import { combineReducers } from "redux";

import { userReducer } from "../contexts/user.context";

export const rootReducer=combineReducers({
    user:userReducer,
});

유저 리듀서 만들기

src/sotre/user/user-reducer.js

import { USER_ACTION_TYPES } from './user.type';

const INITIAL_STATE = {
    currentUser: null,
};

export const userReducer = (state=INITIAL_STATE, action) => {
	const { type, payload } = action;

	switch (type) {
		case USER_ACTION_TYPES.SET_CURRENT_USER:
			return {
				...state,
				currentUser: payload,
			};

		default:
			return state;
	}
};

기존에 Context에서 썼던 reducer를 그대로 가져와서 사용한다.

스토어 적용하기

index.js

import { Provider } from 'react-redux';
import { store } from './store/store';

ReactDOM.render(
	<React.StrictMode>
		<Provider store={store}>
			<BrowserRouter>
				<UserProvider>
					<CategoriesProvider>
						<CartProvider>
							<App />
						</CartProvider>
					</CategoriesProvider>
				</UserProvider>
			</BrowserRouter>
		</Provider>
	</React.StrictMode>,
	document.getElementById('root')

Provider 컴포넌트에 store를 넣어준다.

액션 만들기

src/store/user/user.actions.js

import { USER_ACTION_TYPES } from './user.type';

export const setCurrentUser = (user) => ({
	type: USER_ACTION_TYPES.SET_CURRENT_USER,
	payload: user,
});

실제로 전역에서 state를 바꿀때 사용할 액션이다.

state는 이 액션에 의해서만 변경되어야 한다.

액션 전달하기(fire)

App.js

import { useDispatch } from 'react-redux';
import { setCurrentUser } from './store/user/user.action';

const App = () => {
	const dispatch=useDispatch();

	useEffect(() => {
		const unsubscribe = onAuthStateChangedListener((user) => {
			if (user) {
				createUserDocumentFromAuth(user);
			}
			dispatch(setCurrentUser(user));
		});
		return unsubscribe;
	}, []);
	
	return (...)
}

react-redux의 useDispatch 훅을 사용하여 정의한 action을 리듀서에 전달해서 state를 변경한다.

스토어의 State 가져오기

Navigation.jsx

import { useSelector } from 'react-redux';
import { selectCurrentUser } from '../../store/user/user.selector';

const Navigation = () => {
	const currentUser = useSelector(selectCurrentUser);

	return (...)
}

//user.selector.js
export const selectCurrentUser = (state) => state.user.currentUser;

react-redux의 useSelector훅을 사용하는데 콜백함수로 state의 특정 데이터를 리턴한다.

profile
개발

0개의 댓글