상태 관리 도구에 대해 공부하고 싶어서 인프런에서 Redux에 대한 무료 강의를 하나 수강했다 😀 강의에 따르면 Redux는 React와 함께 사용되기 위하여 만들어졌지만, 현재에는 독립적인 상태 관리 도구로도 충분히 사용될 수 있다고 한다. 나는 React 와 함께 사용해 보고 싶어서 생활코딩 유튜브에 올라온 react-redux 영상까지 한 번 정리해 보고 적용해 보기로 했다!
=> 개발 환경을 로컬에 직접 구축하지 않아도 개발할 수 있도록 하는 클라우드 통합 개발 환경
본 영상에서는 stackblitz
에서 React
를 선택하여 개발을 진행할 것.
import React, { useState } from "react";
import "./style.css";
export default function App() {
const [number, setNumber] = useState(1);
return (
<div id="container">
<h1>Root</h1>
<Left1 number={number}></Left1>
</div>
);
}
function Left1(props) {
return <div>
<h1>Left1 : {props.number}</h1>
<Left2 number={props.number}></Left2>
</div>
}
function Left2(props) {
return <div>
<h1>Left2 : {props.number}</h1>
<Left3 number={props.number}></Left3>
</div>
}
function Left3(props) {
return <div>
<h1>Left3 : {props.number}</h1>
</div>
}
React
로 만든 간단한 프로그램. 여기서 주목할 점은 Root에 있는 상태값을 Left3에 전달하기 위해서는 props
를 통해 타고 타고 내려가야 한다는 점이다...!
실제로 저번 학기 팀 프로젝트에서는 상태 관리 도구에 대해 알지 못해서 똑같은 로직을 사용한 적이 있었다. 사용자 로그인 정보를 모든 컴포넌트에 반영하기 위해서 최상위 컴포넌트인 App
에서 상태를 만들고, 그걸 자식 컴포넌트에 props
로 전달하는 식으로 사용했던 것이다... 하면서도 이 방법밖에 없을 리가 없는데(ㅋㅋㅋㅋ) 라는 생각이 들었던... Redux
를 이용하면 이 문제를 해결할 수 있을 것 같아서 기대가 된다 👀
✔ 지금은 Left
컴포넌트가 3
까지만 있으니까 이 방법이 가능하지만, 만약 상태를 전달하고자 하는 요소가 아주 멀리 떨어져 있으면 이 방법은 현실적으로 사용할 수 없다. 그래서 Redux
와 같은 상태 관리 도구가 필요한 것!
function Right1(props) {
return <div>
<h1>Right1</h1>
<Right2></Right2>
</div>
}
function Right2(props) {
return <div>
<h1>Right2</h1>
<Right3></Right3>
</div>
}
function Right3(props) {
return <div>
<h1>Right3</h1>
</div>
}
이렇게 생긴 Right
요소들을 만들고, 여기에서 Right
에 button
을 만든 다음, 그 button
을 눌렀을 때 number
상태가 변경되게 하고 싶은 것.
export default function App() {
...
<Right1 onIncrease={() => {
setNumber(number + 1);
}}></Right1>
...
}
...
function Right1(props) {
return <div>
<h1>Right1</h1>
<Right2 onIncrease={() => {
props.onIncrease();
}}></Right2>
</div>
}
function Right2(props) {
return <div>
<h1>Right2</h1>
<Right3 onIncrease={() => {
props.onIncrease();
}}></Right3>
</div>
}
function Right3(props) {
return <div>
<h1>Right3</h1>
<input type="button" value="+" onClick={() => {props.onIncrease()}} ></input>
</div>
}
이런 식으로 코드를 작성할 수 있다.
그럼 버튼을 눌렀을 때 제어의 흐름은 위의 그림과 같다. 단지 Right3
에 있는 버튼을 통해 Left3
에 있는 숫자를 바꾸고 싶을 뿐인데, 그 사이에 많은 컴포넌트를 거쳐야 하는 것이다 😢
=> 이걸 props
를 거쳐서 연결하는 것이 아닌, 쉽게 말해 "무선"으로 연결하면 어떨까? 하는 관점이 바로 상태 관리 도구!
✔ react-redux 를 이용해서 react 와 redux 를 연결해 보자.
stackblitz
에서는 이런 식으로 Dependency
를 추가할 수 있다. redux
와 react-redux
를 입력해주면 되는데, react-redux
를 설치하려면 의존성을 가지는 @types/react
, @types/react-dom
, react-native
도 설치하라는 경고가 떠서 같이 설치해 주었다... 사실 TypeScript 와 RN 을 사용할 건 아니라서 설치 안 해도 될 것 같긴 한데 아무튼... 🤔
import { createStore } from 'redux';
import { Provider, useSelector, useDispatch, connect } from 'react-redux';
function reducer(currentState, action) {
if(currentState === undefined) {
return {
number: 1
}
}
const newState = {...currentState};
if(action.type === 'PLUS') {
newState.number++;
}
return newState;
}
const store = createStore(reducer);
...
export default function App() {
return (
<div id="container">
<h1>Root</h1>
<div id="grid">
<Provider store={store}>
<Left1></Left1>
<Right1></Right1>
</Provider>
</div>
</div>
);
}
...
function Left3(props) {
const number = useSelector(state => state.number);
return <div>
<h1>Left3 : {number}</h1>
</div>
}
...
function Right3(props) {
const dispatch = useDispatch();
return <div>
<h1>Right3</h1>
<input type="button" value="+" onClick={() => {
dispatch({type: 'PLUS'});
}} ></input>
</div>
}
connect
는 지금 사용하기에는 조금 어렵고, 재사용성을 위해 사용하는 아이라 이번 강의에서는 생략하신다고 함 👀reducer
와 store
를 사용하는 방식은, 인프런에 올라온 Redux
강의에서와 크게 다른 점이 없는 듯하다!Provider
컴포넌트에는 store
속성을 반드시 넣어주어야 한다 ⭐Provider
로 감싼 Left1
과 Right1
컴포넌트들은 이제 " store
를 사용할 수 있게 되었다" 라고 생각하면 됨!! ✨✨store
에 있는 number
라는 것을 Left3
에서 사용하고 싶을 때 사용할 수 있는 것은 useSelector
Right3
에 있는 button
을 통해 상태값을 바꿔주고 싶을 때 사용할 수 있는 것은 useDispatch
이렇게 하면 props
로 타고타고 값을 전달할 필요 없이, Right3
에서만 값을 바꾸고, Left3
에서만 그 값을 가져와 쓸 수 있게 된다!
이 강의를 듣고 나니 이제 React
에서의 Redux
사용법에 대해서는 어느 정도 알 것 같다 😳 추가적으로 궁금한 건 Redux
를 사용할 때 프로젝트 폴더 구조는 어떻게 해야 하는지 정도...? 이건 관련 글을 더 찾아 봐야겠다 👀