Redux는 리액트 생태계에서 가장 사용률이 높은 오픈소스 JavaScript 상태관리 라이브러리로 state를 이용해 웹 사이트 혹은 애플리케이션의 상태 관리를 해줄 목적으로 사용한다.
상태값을 컴포넌트에 종속시키지 않고 컴포넌트의 바깥에서 상태 관리 함으로써 효율적으로 글로벌 상태 관리 가능
state
: 리덕스에서는 저장하고 있는 상태값(data)으로 딕셔너리 형태({[key]: value})형태로 보관
(이전글) [React] 리액트 상태관리 - ContextAPI
Store(스토어) - Action(액션) - Reducer(리듀서)
// type은 이름 같은 것, 임의의 문자열을 정해 작성
{type: 'CHANGE_STATE', data: {...}}
// 액션생성함수
const changeState = (new_data) => {
return { // 액션을 리턴
type: 'CHANGE_STATE',
data: new_data
}
}
// 임의로 정한 기본 상태값
const initialState = {
name: 'aaa'
}
function reducer(state = initialState, action) {
switch(action.type){
// action의 타입마다 케이스문을 걸어 액션에 따라 새로운 값 return
case CHANGE_STATE:
return {name: 'bbb'};
default:
return false;
}
}
- 리듀서 함수는 이전 상태와 액션 객체를 파라미터로 받는다.
- 파라미터 외의 값에는 의존하면 안된다.
- 이전 상태는 절대로 건드리지 않고, 변화를 준 새로운 상태 객체를 만들어서 반환한다.
- 똑같은 파라미터로 호출된 리듀서 함수는 언제나 똑같은 결과 값을 반환해야 한다.
패키지 설치 : yarn add redux react-redux
기본 파일 생성 : src > redux > modules
데이터 저장할 공간 store 생성 (redux 파일 아래)
// store.js
import {createStore, combineReducers} from "redux";
import cat from "./modules/cat";
const rootReducer = combineReducers({cat});
const store = createStore(rootReducer);
export default store;
action 생성 : "어떤 식으로 수정을 해줘!"
reducer 생성 및 store에 연결
// cat.js (src > redux > modules)
// 1. action 타입 잡아주기
const CHANGE_NAME = "cat/CHANGE_NAME";
// 2. 초기화
const initial_state = {name: "펄이 고양이", age: 5};
// 3. 액션생성함수 생성
export const changeName = (name) => {
return {type: CHANGE_NAME, name};
}
// 4. reducer 작성
export default function reducer(state = initial_state, action={}){
// state = initial_state: state에 설령 아무 값이 오지 않는다하더래도 initial_state 을 기본값으로 할당
// 리듀서는 실제적으로 store에 있는 data값 변경, switch문으로 각각의 액션 타입에 알맞는 작업할 수 있도록 작성
switch(action.type){
case "cat/CHANGE_NAME": {
// 액션생성함수에서 리턴하는 값과 동일한 형태로 리턴
// 그래서 이름을 바꾸고 싶다면 action.name으로 작성해야함
return {...state, name: action.name};
// 스프레드 문법: 불변성 유지때문에 직접 객체 수정하지 않으려고 변경 사항 반영한 새 객체 만들어 넘김
}
default:
return state;
}
}
// 5. store에 넣기 (store.js) -> 6. 컴포넌트와 provider사용해 연결 (index.js)
// -> 컴포넌트에서 쓸 준비 완료!
// 7. 컴포넌트에서 제대로 데이터 가져오기 redux hook사용해서 (App.js)
// index.js
// provider 로 store 연결, 어떤 store를 가져올래도 import
import { Provider } from 'react-redux';
import store from "./redux/store";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
// App.js
// 7. redux hook: useSelector: 구독, useDispatch: 수정 요청
import { useSelector, useDispatch } from "react-redux";
// 9. 어떤 액션을 해!
import {changeName} from "./redux/modules/cat";
function App() {
//8. data 가져오기
const cat = useSelector(state => state.cat);
console.log(cat);
//9. button누르면 수정할거야
const dispatch = useDispatch();
return (
<div className="App">
<p>name::::{cat.name}</p>
<button onClick={() => {
dispatch(changeName("루비")); // 어떤 액션을 해!
}}>이름 바꾸기</button>
</div>
);
}
export default App;