일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- github io
- nextjs .env
- react typescript
- react
- fetch
- git lab
- typescript react
- ngrok실행
- ngrok설치
- bootstrap
- API token
- CSS
- nextjs
- npm styled-reset
- 컨디셔널 렌더링
- Git
- SCSS
- github
- next.js css
- rewrites
- createGlobalStyle
- There isn’t anything to compare
- API 토큰
- getModifierState
- dart 변수
- input type=file
- nextjs 설치
- icon
- styled components
- react env
- Today
- Total
꾸준히 성장하는 개발자
[React 라이브러리] 상태 관리 라이브러리 Redux 본문
Redux 란?
Redux = Reducer + Flux
flux 아키텍쳐에 reducer라는 개념을 도입
Javascript app을 위한 예측 가능한(predictable) state container이다
리액트 뿐만 아니라 Augular, jQuery, vanilla JavaScript 등 다양한 framework와 작동되게 설계되어 있다.
모든 전역 state를 하나의 거대한 object에 모두 담아서 관리한다.
Redux 쓰는 이유
1. props 문법 귀찮을 때 사용
- 모든 component가 props 없이 state 직접 꺼낼 수 있음
2. state 변경 관리할때 사용
- state가 버그가 생겨도 추적이 쉬워 찾기 쉽다
하지만 난 지금 React랑 같이 쓸 거니까 설치는 React-redux도 같이 진행하겠다.
설치방법
npm i redux react-redux
여기에서 우리의 목표는 Left3에서 나오는 숫자를 Right3에서 누르는 버튼으로 숫자 증가를 시켜볼 것이다.
만약 Redux가 없다면 number값을 props를 통해서 전달이 되는데
Right3 → Right2→ Right1→ Roof→ Left1 →Left2→ Left3
const [number, setNumber]= useState(1);
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>
);
}
이렇게 넘겨줘야 할것이다.
그런데 Redux의 state를 사용한다면 좀 더 편하게 전달이 가능하다
이제 Redux를 사용해보자
import { createStore } from 'redux';
import { Provider, useSelector, useDispatch, connect } from 'react-redux';
redux를 사용하기 위해 createStore을 불러온다.
Provider: component,
state를 어떤 component에 제공할 것인가 에 대한 가장 바깥쪽의 울타리를 정하는 것
useSelector: 어떤 state값을 쓰고 싶은지 선택할 때 사용
useDispatch: state값을 변경시킬 때 사용
connect: 재사용을 할 때 사용 / 지금은 사용하지 않는다
state 수정하는 방법 / reducer
reducer
- flux 아키텍쳐 중 dispatcher를 대체
- 현재 state와 들어온 action을 이용하여 다음 state를 결정하는 순수함수
(순수함수란? 동일한 인자가 들어갈 경우 항상 같은 값이 나오는것
function add(a,b){a+b} => add(1,2) => 3 반환
)
- state의 자료형은 자유 (primitive, 배열, 객체 등)
- 상태를 update한다면 대입 연산이 아닌 다음 state를 반환. (immutable)
store
- 하나의 거대한 object
- store에 reducer를 등록
- dispatch된 action을 모든 reducer에게 전달
- store가 처음 생성될 때 INIT action을 reducer에게 전달하여 초기 state를 저장
// state의 관리를 하는 전용 장소 or 앱의 상태를 보관하는 Redux 저장소
const store=createStore(reducer);
// state를 어떻게 바꿀것인가
function reducer(현재state값, 어떻게 바꿀것인지 요청을 받는 액션){
// 만약 state가 정의되지 않았다면?
if(현재state값 === undefined){
return{
number : 기존값,
}
}
// redux는 각각의 state의 변화를 불변하게 유지해야 하는데 어떻게 유지하느냐
// 새로운 state를 만드는데 과거의 state를 복제한다.
const 새로운state = { ... 현재state}
return 새로운 state 값
}
redux는 각각의 state의 변화를 불변하게 유지해야 하는데 어떻게 유지하느냐
-> 새로운 state를 만드는데 과거의 state를 복제한다.
const [number, setNumber]= useState(1);
그리고 우린 이 값은 필요가 없어졌으니 지우도록 한다.
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);
Provider
react-redux 라이브러리에 내장되어있는, 리액트 앱에 store를 손쉽게 연동할 수 있도록 도와주는 컴포넌트
이 컴포넌트를 불러온 다음에, 연동할 컴포넌트를 감 싸준 다음에Provider 컴포넌트의 props로 store 값을 설정해준다.
Provider를 사용하면서 prop 중에 store라는 것을 반드시 정의해줘야 한다.
store는 위에 useStore( )를 정의해놓은 것을 가져오면 된다.
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>
);
}
useSelector
현재 우리는 위의 number값을 무선으로 연결하고 싶은 것인데
그래서 사용하는 것은 useSelector이다.
function Left3(props) {
console.log('3');
const number = useSelector((state) => state.number);
return (
<div>
<h1>Left3 : {number}</h1>
</div>
);
}
useSelector는 함수를 인자로 받는다.
function f(state){
return state.number
}
const number=useSelector(f);
이렇게 작성되는 것을 위처럼 좀 더 간단하게 작성할 수 있는 것이다.
dispatch
우리는 저기에 있는 number값을 Right3에서 바꿔줄 수 있는 button을 설정해보자
function Right3(props) {
const dispatch = useDispatch();
return (
<div>
<h1>Right3</h1>
<input
type="button"
value="+"
onClick={() => {
dispatch({ type: 'PLUS' });
}}
></input>
</div>
);
}
dispatch를 가져와서
onClick에 'PLUS'라는 action을 전달한다. 그렇게 되면 reducer가 호출된다.
액션을 선언할때에는 위와 같이 대문자로 선언한다.
import React, { useState } from 'react';
import './style.css';
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 Left1(props) {
return (
<div>
<h1>Left1 </h1>
<Left2></Left2>
</div>
);
}
function Left2(props) {
console.log('2');
return (
<div>
<h1>Left2 : </h1>
<Left3></Left3>
</div>
);
}
function Left3(props) {
console.log('3');
const number = useSelector((state) => state.number);
return (
<div>
<h1>Left3 : {number}</h1>
</div>
);
}
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) {
const dispatch = useDispatch();
return (
<div>
<h1>Right3</h1>
<input
type="button"
value="+"
onClick={() => {
dispatch({ type: 'PLUS' });
}}
></input>
</div>
);
}
https://www.youtube.com/watch?v=yjuwpf7VH74&t=53s
진상현강사님 강의 + 생활코딩 유투브에서 배운 내용 정리 완료
https://stackblitz.com/edit/react-pf1cxs?file=src%2FApp.js
React-Redux : with redux final - StackBlitz
stackblitz.com
'React' 카테고리의 다른 글
[React Hooks] useRef (0) | 2022.05.23 |
---|---|
[React] React state 비동기성 (0) | 2022.05.20 |
React with Typescript 설치 (0) | 2022.05.19 |
[React] API를 이용한 data 가져오기 (0) | 2022.05.12 |
React - jsx , state, props (0) | 2022.05.06 |