const [state, dispatch] = useReducer(reducer, initialState);
import React, { useReducer } from 'react';
// reducer 함수
const reducer = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
case 'RESET':
return 0;
default:
return state;
}
};
const initialState = 0;
const Counter = () => {
// useReducer를 사용하여 상태 관리
const [count, dispatch] = useReducer(reducer, initialState);
const increment = () => {
dispatch({ type: 'INCREMENT' });
};
const decrement = () => {
dispatch({ type: 'DECREMENT' });
};
const reset = () => {
dispatch({ type: 'RESET' });
};
return (
<div>
<h1>Count: {count}</h1>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
<button onClick={reset}>Reset</button>
</div>
);
};
export default Counter;
Action(액션) 객체
가 dispatch()
메소드에 전달된다.
dispatch(액션)
를 통해 Reducer
를 호출한다.
Reducer
는 새로운 Store
를 생성한다.
👉 왜 이런 공식을 따를까?
1 - 7 번까지 차근차근
npm install redux
npm install react-redux
Provider 감싸주기 → Store 를 제공해주기 위해서이다.
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<BrowserRouter>
<App />
<BrowserRouter>
</Provider>
);
리덕스 폴더에 Store.js 파일 만들어주기.
import {createStore} from "redux";
let store = createStore(reducer)
// let store = createStore(rootReducer, composeWithDevTools(applyMiddleware(thunk)));
let store = configureStore({
reducer:{
auth : authenticateReducer,
product : productReducer
},
})
리덕스 폴더 안에 리듀서 폴더를 만들고 그 안에 reducer.js 파일을 만들어 준다.
let initialState = {};
function reducer(state = initialState, action) {
}
export default reducer;
import { combineReducers } from 'redux';
export default combineReducers({});//컴바인 리듀서 안에는 항상 객체가 들어간다.
// 객체 안에는 리듀서들을 넣는다.
dispatch({type : "ADD_CONTACT", payload : {name,phone}}); //Action 보내기
이렇게 action 을 던지면 reducer 에서 받는다.
let initialState = {
contactList: []
};
function reducer(state = initialState, action) {
const {type, payload} = action
switch (type) {
case "ADD_CONTACT":
return { ...state, contactList: [...state.contactList, { name: payload.name, phone: payload.phone, },], }
default :
return {...state};
}
}
const {contact, keyword} = useSelector((state) => state); //store의 contact, keyword를 가져온 것
기존에 만들었던 영화 웹 페이지 redux 적용해보기.
redux toolkit을 사용하여 적용하기.
import { configureStore } from "@reduxjs/toolkit";
import { logger } from "redux-logger";
import MovieStore from "./MovieStore";
const store = configureStore({
reducer: {
MovieStore: MovieStore,
},
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(logger),
});
export default store;
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
movies: [],
};
const MovieSlice = createSlice({
name: "movie",
initialState: initialState,
reducers: {
updateMovieStore: (state, action) => {
state.movies = action.payload
}
},
});
export const { updateMovieStore } = MovieSlice.actions;
export default MovieSlice.reducer;
// toolkit
useEffect(() => {
setLoading(true);
fetch(url)
.then(res => res.json())
.then(data => {
dispatch(updateMovieStore(data.data.movies));
setLoading(false);
})
.catch(err => {
setError(err);
setLoading(false);
})
}, [])
const { movies } = useSelector((state) => state.MovieStore);
...생략
Redux Toolkit을 사용한 후 상태 관리가 훨씬 간편해졌다. Redux Toolkit은 간결한 구문과 개발 생산성을 위한 많은 유틸리티 함수를 제공하여 코드량을 줄이고 개발 속도를 향상시켰다. Slice를 통해 리듀서와 액션 생성자를 한 곳에서 관리할 수 있어 코드의 일관성을 유지할 수 있었다. 또한 불변성을 자동으로 처리해주기 때문에 상태 업데이트에 대한 실수를 방지할 수 있었다. Redux Toolkit는 DevTools 지원과 비동기 작업을 위한 createAsyncThunk도 들어있어서 복잡한 것이 좀 사라졌다. 전반적으로 Redux Toolkit은 Redux의 복잡성을 감소시키고 개발자 경험을 향상시킨 강력한 도구인 것 같다.