useState를 사용 할 경우 컴포넌트 내부에 state를 만들고, 함수로 state를 바꾼다. 그렇기 때문에 state는 컴포넌트에 종속된다.
redux는 컴포넌트에 종속되지 않고, 상태관리를 컴포넌트 바깥에서 한다.
프로젝트 루트레벨에서 store라는 곳에 state를 저장하고, 모든 컴포넌트는 store에 구독을 하면서 state와 그 state를 바꾸는 함수를 전달 받게 된다.
함수를 바꿈으로 state가 바뀌면 해당 state를 바라보고 있는 컴포넌트는 모두 리렌더링 된다.
컴포넌트 안에 컴포넌트 안에 컴포넌트 안에 컴포넌트가 있을 때 컴포넌트들 간에 데이터를 주고 받을 때 props 로 연결해야 한다. 비유하자면, props라는 전선으로 컴포넌트들을 연결한 것이라고 할 수 있다.
Redux가 이 전선을 와이파이처럼 무선으로 연결 시켜주는 역할을 한다.
npm install redux react-redux
import { Provider, useSelector, useDispatch } from "react-redux";
redux를 사용할 때튼 store와 reducer를 만든 후 사용한다
provider 어떤 컴포넌트에게 제공할 것인가에 대한 가장 바깥쪽에 울타리에 묶어서 사용한다.
porvider의 prop으로는 store를 반드시 정의 해준다.
아래와 같이 Root 컴포넌트 안의 가장 부모 Left1과 Right1을 provider로 묶어 사용한다.
이제는 provider로 묶어준 Left1과 Right1은 store를 사용할 수 있게 되었다.
<script>
import React, { useState } from "react";
import { createStore } from "redux";
import { Provider, useSelector, useDispatch } from "react-redux";
function reducer(currentState, action) {
if (currentState === undefined) {
return {
number: 1
};
}
const newState = { ...currentState };
return newState;
}
const store = createStore(reducer);
export default function App() {
return (
<div id="container">
<h1>Root </h1>
<div id="grid">
<Provider>
<Left1 />
<Right1 />
</Provider>
</div>
</div>
);
}
function Left1(props) {
return (
<div>
<h1>Left1</h1>
<Left2 />
</div>
);
}
function Left2(props) {
return (
<div>
<h1>Left2</h1>
<Left3 />
</div>
);
}
function Left3(props) {
return (
<div>
<h1>Left3</h1>
</div>
);
}
function Right1(prps) {
return (
<div>
<h1>Right3</h1>
<Right2 />
</div>
);
}
function Right2(props) {
return (
<div>
<h1>Rigth2</h1>
<Right3 />
</div>
);
}
function Right3(props) {
return (
<div>
<h1>Right3</h1>
<input
type="button"
value="+"
onClick={() => {
props.onIncrease;
}}
></input>
</div>
);
}
</script>
reducer에 있는 number의 값을 Left3에 전달 할려면 어떻게 해야할까 , 이럴때 사용하는것이 useSelector이다.
useSelector는 함수를 인자로 받는다.
전역으로 선언한 store가 말단에 있는 Left3에 무선으로 number값을 전달 했다.
<script>
function Left3(props) {
const number = useSelector((state) => state.number);
return (
<div>
<h1>Left3 : {number}</h1>
</div>
);
}
</script>
Right3에 있는 +버튼을 클릭했을 때 Left3에 있는 number를 증가 시켜보자.
useDispatch를 통해 store의 action 값을 가져온다.
버튼을 클릭하면 action.type이 "PLUS"일 때 newState.number (1) 의 값을 증가시킨다.
<script>
function reducer(currentState, action) {
if (currentState === undefined) {
return {
number: 1
};
}
const newState = { ...currentState };
if (action.type === "PLUS") {
newState.number++;
}
return newState;
}
function Right3(props) {
const dispatch = useDispatch();
return (
<div>
<h1>Right3</h1>
<input
type="button"
value="+"
onClick={() => {
dispatch({ type: "PLUS" });
}}
></input>
</div>
);
}
</script>