자바스크립트 애플리케이션에서 상태를 효율적으로 관리할 수 있게 도와주는 라이브러리
상태 변화를 일으킬 때 참조하는 객체
{
type: "ADD_TODO",
payload: {
id: 0,
text: "redux"
}
}
type으로 액션을 구분하고 payload의 값으로 State를 업데이트 한다.
액션객체를 만드는 헬퍼함수
const createAction = (type, payload) => ({ type, payload });
이전 상태와 액션을 입력받아 변화를 일으키는 함수.
반드시 순수함수여야 한다.(리턴 값은 파라미터 값에만 의존하며 언제나 같은 결과를 출력)
State의 변화는 Reducer에서만 일어나야한다
컴포넌트 외부에 있는 State 저장소
리듀서 함수를 호출하여 액션에 맞게 상태를 변화시킨다.
참고)) 리액트가 없이 쓰는 리덕스
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는 이 액션에 의해서만 변경되어야 한다.
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를 변경한다.
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의 특정 데이터를 리턴한다.