// 리덕스, Redux
- redux에 대해서는 이전 글에서 작성했기 때문에 이번에는 리액트에서 사용하는 redux에 대해 정리할 예정이다.
- 참고: https://sorrel012.tistory.com/387
1. redux, react-redux 설치
npm install redux react-redux
2. 저장소 생성
import { createStore } from 'redux';
const 저장소명 = createStore();
3. Reducer 함수 추가
const reducer함수명 = (state = 기본값, action) => {
return {
};
}
- 기존 state, action 2개의 parameter를 받는다.
- 새로운 상태 객체를 return 한다. (이론적으로는 다른 형태로도 가능하지만, 실제로는 객체 return)
4. 저장소에 reducer 함수 전달
import { createStore } from 'redux';
const 저장소명 = createStore(reducer함수명);
5. 컴포넌트에서 사용할 수 있게 저장소 export
import { createStore } from 'redux';
const 저장소명 = createStore(reducer함수명);
export default 저장소명;
6. index.js 파일에 저장소를 import 한다.
import { Provider } from 'react-redux';
import store from './store';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>,
);
- 모든 컴포넌트에서 사용하기 위에 컴포넌트 트리의 최상단에 위치하는 index.js 파일에 수정·추가한다.
7. 사용하고자 하는 컴포넌트에서 custom hook을 import 한다.
import { useDispatch, useSelector } from 'react-redux';
- useStore hook도 사용할 수 있지만, 저장소가 관리하는 state를 우리가 자동으로 선택할 수 있어 useSelector hook이 더 편리하다.
- useDispatch hook으로 action을 dispatch한다.
7. useSelector로 state를 선택한다.
const 변수명 = useSelector((state) => state.원하는data명);
- 저장소의 state가 변경되면 자동으로 컴포넌트 함수가 재실행되기 때문에 최신의 state를 얻을 수 있다.
7. 사용하고자 하는 컴포넌트에서 useDispatch hook으로 action을 dispatch한다.
const dispatch = useDispatch();
const 함수명 = () => {
dispatch(action 객체)
}
import { createStore } from 'redux';
const initialState = { counter: 0, showCounter: true };
const counterReducer = (state = initialState, action) => {
if (action.type === 'increment') {
return {
counter: state.counter + action.amount,
showCounter: state.showCounter,
};
}
if (action.type === 'decrement') {
return {
counter: state.counter - 1,
showCounter: state.showCounter,
};
}
if (action.type === 'toggle') {
return {
counter: state.counter,
showCounter: !state.showCounter,
};
}
return state;
};
const store = createStore(counterReducer);
export default store;
import classes from './Counter.module.css';
import { useDispatch, useSelector } from 'react-redux';
const Counter = () => {
const dispatch = useDispatch();
const counter = useSelector((state) => state.counter);
const showCounter = useSelector((state) => state.showCounter);
const incrementHandler = (amount) => {
dispatch({ type: 'increment', amount: amount });
};
const decrementHandler = () => {
dispatch({ type: 'decrement' });
};
const toggleCounterHandler = () => {
dispatch({ type: 'toggle' });
};
return (
<main className={classes.counter}>
<h1>Redux Counter</h1>
{showCounter && <div className={classes.value}>{counter}</div>}
<div>
<button onClick={() => incrementHandler(1)}>Increment</button>
<button onClick={() => incrementHandler(5)}>Increment 5</button>
<button onClick={decrementHandler}>Decrement</button>
</div>
<button onClick={toggleCounterHandler}>Toggle Counter</button>
</main>
);
};
export default Counter;
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import './index.css';
import App from './App';
import store from './store';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>,
);
'클라이언트 > React' 카테고리의 다른 글
[리액트(React)] Redux Toolkit (0) | 2024.02.16 |
---|---|
[리액트(React)] Redux with Class-based Component (0) | 2024.02.15 |
[리액트(React)] Custom Hook (0) | 2024.02.09 |
[리액트(React)] Data Fetching & HTTP Request (0) | 2024.02.08 |
[리액트(React)] Class-based Component (0) | 2024.02.07 |