- 리덕스는 크로스 컴포넌트 상태, 앱와이드 상태를 위한 상태 관리 시스템이다.
- 일반적인 프로그래밍 개념으로 리듀서 함수는 입력을 변환해서 새로운 출력, 새로운 결과를 뱉어내는 기능을 수행한다.
npm install redux
: redux는 react와 연관없는 패키지이다.
npm install react-redux
: redux와 react앱의 작업을 쉽게 하기위해 해당 패키지 설치.
subscribe()
: 인자로 구독자 함수를(저장소를 사용하는 컴포넌트) 취함. 리덕스는 데이터와 저장소가 변경될 때마다 인자로 받은 함수(구독자 함수)를 실행시킴.getState()
: createStore()로 생성된 저장소에서 사용 가능한 메서드, 업데이트된 저장소 데이터를 반환함.dispatch()
: 액션을 발송하는 메소드, 액션은 객체타입createStore(리듀서 함수)
: Store생성 메서드👾 redux-demo.js
// js에서 서드파티패키지를 inport하는 방법
const redux = require("redux");
const counterReducer = (state = { counter: 0 }, action) => {
if (action.type === "increment") {
return {
counter: state.counter + 1,
};
}
if (action.type === "decrement") {
return {
counter: state.counter - 1,
};
}
// 초기값 state 반환
return state;
};
const store = redux.createStore(counterReducer);
/* 구독자 컴포넌트 */
const counterSubscriber = () => {
// 저장소에 있는 업데이트된 데이터 반환
const latestState = store.getState();
console.log(latestState);
};
// subscribe()메서드는 인자로 counterSubscriber함수를 취함.
// 리덕스는 데이터와 저장소가 변경될 때마다 인자로 받은 함수(구독자 함수)를 실행시킴.
store.subscribe(counterSubscriber);
// dispatch()는 액션을 발송하는 메소드, 액션은 객체타입
// 💡 action을 dispatch하면 리듀서 함수에서 해당 type의 조건문이 없어도 리듀서 함수는 실행된다!!
store.dispatch({ type: "increment" });
store.dispatch({ type: "decrement" });
💡 파라미터 state에 초기값을 설정하는 이유
💡 파라미터로 함수의 포인터를 전달하는 이유는 리듀서와 구독함수를 모두 리덕스가 실행하기 때문
useSelector
: 자동으로 스토어가 관리하는 상태의 일부를 선택하게 해줌.(= 자동 구독 설정)useStore
: 저장소의 인스턴스를 반환합니다. 이것을 사용하는 구성 요소가 업데이트되지 않기 때문에 일반적으로 권장되지 않음. 이러한 경우 useEffect와 같은 반응 후크를 사용하여 명시적으로 구성 요소를 업데이트해야 함!connect
: 함수형 컴포넌트에서 래퍼로 사용, 클래스 컴포넌트 근처에서 클래스 컴포넌트를 스토어에 연결useDispatch
: 인수로 아무것도 전달하지 않고, 실행할 수 있는 dispatch function을 반환함. Redux store에 대한 action을 보냄.👾 store/index.js
import { createStore } from "redux";
const counterReducer = (state = { counter: 0 }, action) => {
if (action.type === "increment") {
return { counter: state.counter + 1 };
}
if (action.type === "decrement") {
return { counter: state.counter - 1 };
}
return state;
};
const store = createStore(counterReducer);
export default store;
👾 index.js
import { Provider } from 'react-redux'
import counterStore from './store/index'
root.render(<Provider store={counterStore}><App /></Provider>);
👉🏻 Provider의 store프롭에 연결할 store지정
👉🏻 counterStore: 제공자 컴포넌트, store프롭에 연결함으로써 리덕스 스토어를 제공함.
👾 Counter.js
import { useSelector } from 'react-redux'
const Counter = () => {
...
// 리액트 스토어에 자동 구독 설정
// 스토어에 데이터가 변경될 때마다 자동으로 가장 최신의 counter를 받음.
const counter = useSelector(state=> state.counter);
}
👉🏻 자동으로 리덕스 스토어가 바뀐다면 컴포넌트 함수가 재실행 됨!!
👾 Counter.js
import { useSelector, useDispatch } from 'react-redux'
const Counter = () => {
...
// 실행할 수 있는 dispatch function을 반환.
const dispatch = useDispatch();
// store에 있는 counter 가져옴.
const counter = useSelector(state => state.counter);
const incrementHandler = () => {
// dispatch function을 호출하는 argument
dispatch({type: 'increment'});
}
const decrementHandler = () => {
dispatch({type: 'decrement'});
}
}
...
return (
<div>{counter}</div>
<button onClick={incrementHandler}>증가 버튼</button>
<button onClick={decrementHandler}>감소 버튼</button>
);
: 버튼 클릭시 amount씩 값 증가
👾 index.js
if (action.type === "increment") {
return { counter: state.counter + action.amount };
}
👾 Counter.js
const incrementHandler = () => {
dispatch({type: 'increment', amount: 5 });
}
👉🏻 증가값을 유동적으로 설정 가능하다.