리액트 상태 관리 라이브러리입니다. 리덕스를 사용하면 컴포넌트의 상태 업데이트 관련 로직을 다른 파일로 분리시켜서 더욱 효율적으로 관리할 수 있습니다.
1. getState()
2. dispatch(action)
3. subscribe(listener)
4. replaceReducer(nextReducer)
//index.css
.toggle{
border : 2px solid black;
width: 64px;
height: 64px;
border-radius: 32px;
box-sizing: border-box;
}
.toggle.active{
background: yellow;
}
// index.html
<html>
<head>
<link rel="stylesheet" type="text/css" href="index.css"/>
</head>
<body>
<div class="toggle"></div>
<hr/>
<h1>0</h1>
<button id="increase">+1</button>
<button id="decrease">-1</button>
<script src="./index.js"></script>
</body>
</html>
//index.js
//DOM레퍼런스
const divToggle = document.querySelector('.toggle');
const counter = document.querySelector('h1');
const btnIncrease=document.querySelector('#increase');
const btnDecrease = document.querySelector('#decrease');
//액션타입
const TOGGLE_SWITCH ='TOGGLE_SWITCH';
const INCREASE = 'INCREASE';
const DECREASE = 'DECREASE';
//액션 생성함수
const toggleSwitch = ()=>({type : TOGGLE_SWITCH})
const increase = difference=>({type:INCREASE,difference})
const decrease = ()=>({type:DECREASE})
//초기값 설정
const initialState={
toggle : false,
counter:0
}
- 리듀서 함수가 맨 처음 호출되 때는 state 값이 undefined이다. 해당 값이 undefined로 주어졌을 때는 initalState를 기본값으로 설정하기 위해 함수의 파라미터 쪽에 기본값이 설정되어 있다.
- 리듀서에서는 상태의 불변성을 유지하면서 데이터에 변화를 일으켜야 한다.
//index.js
//state가 undefined일때는 initialState를 기본값으로 사용
function reducer(state= initialState, action){
//action.type에 따라 다른 작업을 처리함
switch(action.type){
case TOGGLE_SWITCH:
return{
...state, //spread 연산자를 활용해 불변성 유지 필요
toggle:!state.toggle
};
case INCREASE:
return{
...state,
counter: state.counter + action.difference
};
case DECREASE:
return{
...state,
counter:state.counter-1
};
default:
return state;
}
}
//index.js
import {createStore} from 'redux';
(...)
const store = createStore(reducer);
이렇게 작성하였더니 아래와 같이 createStore
에 밑줄이 그어져 있다.
그래서 redux 공식 문서 가보니 아래와 같이 써져있는데 해석하자면
- 지원 중단으로 인해 가져오고 사용할 때 시각적 취소선이 표시됩니다.createStore, 그러나 런타임 오류나 경고는 없습니다 .
- createStore계속해서 무기한으로 작동하며 제거되지 않습니다 . 그러나 오늘날 우리는 모든 Redux 사용자가 모든 Redux 로직에 Redux Toolkit을 사용하기를 원합니다
- 취소선을 보고 싶지 않다면 3가지 방법이 있다.
- RTK configureStore을 쓰거나
- 아무것도하지 마세요. 이는 시각적인 취소선일 뿐이며 코드 작동 방식에는 영향을 주지 않습니다. 그냥 무시하세요
- 아래와 같은 코드로 쓰면 취소선이 안보인다.
import { legacy_createStore as createStore } from 'redux'
➡️ 그래서 나는 3번째 방법을 쓰기로 했다.
render이란 함수는 상태가 업데이트 될때마다 호출되며, 리액트의 render 함수와는 다르게 이미 html을 사용하여 만들어진 ui의 속성을 상태에 따라 변경해준다. 즉, 브라우저, 화면에 페인트한다는 소리..
//index.js
const render=()=>{
//현재 상태를 불러오는 store 메서드
const state = store.getState();
if(state.toggle){
//toggle이 참이라면, 클래스 이름을 추가한다.
divToggle.classList.add('active'); /
}else{
//toggle이 거짓이라면 클래스 이름을 제거한다.
divToggle.classList.remove('active');
}
//counter의 text를 state.counter로 바꿔준다.
counter.innerText =state.counter
}
render()
- subscribe를 사용하여 스토어의 상태가 바뀔 때마다 위에 만든 render함수가 호출되도록 해준다.
- subscribe 함수의 파라미터로는 함수 형태의 값을 전달한다. 전달된 함수는 추후 액션이 발생하여 상태가 업데이트될때마다 호출된다.
//index.js
store.subscribe(render)
- 액션을 발생시키는 것을 디스패치라고 한다.
- 디스패치를 할때는 스토어의 내장 함수 dispatch를 사용합니다.
- 파라미터는 액션객체를 넣어주면됩니다.
//index.js
divToggle.onclick =()=>{
store.dispatch(toggleSwitch());
}
btnIncrease.onclick=()=>{
store.dispatch(increase(1))
};
btnDecrease.onclick=()=>{
store.dispatch(decrease())
}
하나의 스토어
가 들어가 있습니다.불변성
을 지켜야 합니다.순수함수
여야 합니다.