Redux
import { configureStore, createSlice } from '@reduxjs/toolkit';
import React from 'react';
import { Provider, useDispatch, useSelector } from 'react-redux';
const counterSlice = createSlice({
name: 'counterSlice',
initialState: { value: 0 },
reducers: {
// reducer 가 아닌 reducers임
up: (state, action) => {
console.log(action); // { type: "counterSlice/up", payload: 2 }
state.value = state.value + action.payload;
},
},
});
const store = configureStore({
reducer: {
counter: counterSlice.reducer,
},
});
function Counter() {
const dispatch = useDispatch();
const count = useSelector((state) => {
// console.log(state); // state = {counter: {value: 0}}
return state.counter.value;
});
return (
<div>
{/* 리덕스 툴킷은 리듀서 함수를 참고해서 자동적으로 actionCreator를 생성해준다. */}
<button onClick={() => dispatch(counterSlice.actions.up(2))}>+</button>
{count}
</div>
);
}
export default function App() {
return (
<Provider store={store}>
<div>
<Counter />
</div>
</Provider>
);
}
React Redux
Redux toolkit
Redux + React Redux 구조는 간단히 이렇다.
import React from 'react';
import { Provider, useDispatch, useSelector } from 'react-redux';
import { createStore } from 'redux';
function reducer(state, action) {
if (action.type === 'up') {
return { ...state, value: state.value + action.step };
}
}
const initialState = { value: 0 };
const store = createStore(reducer, initialState);
function Counter() {
const dispatch = useDispatch();
const count = useSelector((state) => state.value);
return (
<div>
<button onClick={() => dispatch({ type: 'up', step: 2 })}>+</button>
{count}
</div>
);
}
export default function App() {
return (
<Provider store={store}>
<div>
<Counter />
</div>
</Provider>
);
}
여기에 Redux-toolkit 을 적용하면 아래와 같다.
import { configureStore, createSlice } from '@reduxjs/toolkit';
import React from 'react';
import { Provider, useDispatch, useSelector } from 'react-redux';
// counter 라는 작은 스토어 생성
const counterSlice = createSlice({
name: 'counterSlice',
initialState: { value: 0 },
reducers: {
// reducer 가 아닌 reducers임
up: (state, action) => {
console.log(action); // { type: "counterSlice/up", payload: 2 }
state.value = state.value + action.payload;
},
},
});
// store 안에 작은 스토어를 configure 해준다.
const store = configureStore({
reducer: {
counter: counterSlice.reducer,
},
});
function Counter() {
const dispatch = useDispatch();
const count = useSelector((state) => {
return state.counter.value; // state = {counter: {value: 0}}
});
return (
<div>
<button onClick={() => dispatch({ type: 'up', step: 2 })}>+</button>
<button onClick={() => {
// dispatch({ type: 'up', step: 2 });
{/* 리덕스 툴킷은 리듀서 함수를 참고해서 자동적으로 actionCreator를 생성해준다. */}
{/* 단, actionCreator는 reducers만 자동 생성, 비동기 reducer는 직접 생성해야 한다. */}
dispatch(counterSlice.actions.up(2)
})}>+</button>
{count}
</div>
);
}
export default function App() {
return (
<Provider store={store}>
<div>
<Counter />
</div>
</Provider>
);
}
위 구조가 기본 구조이며, 보통 위 구조를 아래처럼 나눠서 관리한다.