티스토리 뷰
Redux를 React에서 사용하는 방법을 알아본다.
React-redux 설치
터미널에서 아래의 명령어를 실행한다.
npm i redux react-redux
Provider
index.js 에서 Provider 컴포넌트로 App 컴포넌트를 감싼다.
그리고 store.js 파일을 임포트하여 Provider의 props로 전달한다.
이렇게 하면 최상위에 store가 연결되므로 각각의 컴포넌트에 store를 임포트해야하는 번거로움이 줄어든다.
import { Provider } from 'react-redux';
import store from './store';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
store.js 에 store, reducer, action creators를 작성한다.
Store
createStore로 스토어를 생성한다. 이 때 인자로 reducer 함수를 반드시 전달해야한다.
//스토어 생성
const store = createStore(reducer);
export default store;
reducer
리듀서 함수는 state와 action을 이용해서 새로운 state를 반환하는 함수이다.
action의 type에 따른 로직을 switch case문을 통해 구현한다.
return은 반드시 원본을 건드리지 않고 복제본을 만들어 반환해야 함을 잊지말아야 한다.
ADD의 경우 기존 state를 spread 문법을 이용하여 펼친 후, 뒤에 추가될 객체를 넘겨준다.
DELETE의 경우 filter 배열 메서드를 이용하여 원본 배열이 직접 변하는 것이 아닌 새 배열을 반환하도록 했다.
const reducer = (state = [], action) => {
switch (action.type) {
case ADD:
return [...state, { text: action.text, id: Date.now() }];
case DELETE:
return state.filter((toDo) => toDo.id !== action.id);
default:
return state;
}
};
액션 타입(action type)/액션 생성자(action creators)
액션 타입은 상수로 만들어준다.
액션 생성자는 dispatch함수에 객체 형태로 전달했던 액션을 만드는 함수이다.
액션 생성자는 반드시 export 해주어야 한다.
//액션 타입
const ADD = 'ADD';
const DELETE = 'DELETE';
//액션 생성자
export const addToDo = (text) => {
return {
type: ADD,
text,
};
};
export const deleteToDo = (id) => {
return {
type: DELETE,
id: parseInt(id),
};
};
connect
connect 함수는 리액트 컴포넌트와 리덕스 스토어를 연결하는 함수이다.
이 함수를 쓰기 전에 리액트 컴포넌트로부터 리덕스와 관련된 것들을 container 컴포넌트로 분리한다.
container 컴포넌트는 기존 리액트 컴포넌트를 감싸는 컴포넌트로,
여기서 리덕스와 관련한 일을 수행하게 되고(스토어와 데이터를 주고받게 되고)
리액트 컴포넌트는 container 컴포넌트에서 props로 데이터를 전달받아 단순히 화면에 표시되는 일만 하게 된다.
container 컴포넌트에서 connect를 작성한다.
connect 함수의
첫번째 괄호에는 mapStateToProps, mapDispatchToProps 함수가,
두번째 괄호에는 연결할 컴포넌트가 전달된다.
즉, connect() 를 호출해서 반환받은 함수에, 두번째 괄호의 컴포넌트를 파라미터로 넣어서 호출한 것이다.
connect 함수의 인자는 없을 수도 있고
하나만 있다면 mapStateToProps이고 둘 다 있다면 mapStateToProps, mapDispatchToProps이다.
mapDispatchToProps만 있다면 (null, mapDispatchToProps)와 같이 넘겨준다.
import { connect } from 'react-redux';
export default connect(mapStateToProps, mapDispatchToProps)(Home);
connect를 이용하지 않는다면 아래와 같이 코드를 작성하여 state를 받아오고,
상태값이 변경됐을 때 subscribe를 이용해서 새로운 상태값을 받아와 컴포넌트에 전달해야한다.
export default class extends Component {
state = {
number: store.getState().number,
};
componentDidMount() {
store.subscribe(() => {
this.setState({
number: store.getState().number,
});
});
}
render() {
return <DisplayNumber number={this.state.number}></DisplayNumber>;
}
}
하지만 connect와 mapStateToProps, mapDispatchToProps 함수를 이용하면 이러한 과정을 자동으로 해주어
스토어의 상태값과 디스패치 함수를 컴포넌트의 props로 쉽게 전달할 수 있다.
mapStateToProps
mapStateToProps 함수는 스토어의 state를 리액트 컴포넌트의 props로 전달해주는 함수이다.
return값은 객체형태이며, key에 해당하는 것은 props의 이름, value는 props에 전달하고 싶은 값을 의미한다.
컴포넌트에 number라는 props를 직접 전달해주는 것과 동일하다.
function mapStateToProps(state) {
return {
number: state.number, // = <DisplayNumber number={this.state.number}></DisplayNumber>
};
}
export default connect(mapStateToProps)(DisplayNumber);
mapDispatchToProps
mapDispatchToProps 함수는 이벤트가 일어났을 때, 액션을 dispatch하여 리액트 컴포넌트의 props로 전달하는 함수이다.
컴포넌트에 이벤트(dispatch)를 props로 직접 전달해주는 것과 동일하다.
function mapDispatchToProps(dispatch) {
return {
onClick: (size) => {
dispatch({
type: 'INCREMENT',
size: size,
});
},
};
}
export default connect(null, mapDispatchToProps)(AddNumber);
둘 다 컴포넌트 안에서 직접 리덕스를 사용하지 않고
리덕스와 관련한 기능을 함수로 따로 뺐다고 생각하면 된다.
컴포넌트는 오직 props를 받고 화면에 표시하는 기능만을 수행하게 된다.
소스코드 출처 및 참고
- 생활코딩 react-redux
- 노마드 코더 redux
- 벨로퍼트 https://velog.io/@velopert/Redux-3-리덕스를-리액트와-함께-사용하기-nvjltahf5e
- Total
- Today
- Yesterday
- 프로젝트
- CSS
- RenderTree
- Big Ω
- 구조체
- 폼
- 동기처리
- 연결리스트
- Dom
- 선택자
- intersectionObserver
- vanillajs
- 포인터
- malloc
- valgrind
- 비구조화할당
- 문자열
- sr-only
- 선형검색
- form
- CSSOM
- overflow
- capturing
- 함수
- float
- 이벤트위임
- Typography
- pseudo
- HTML
- 구조분해할당
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |