https://redux.js.org/tutorials/quick-start
Redux란?
state를 관리해주는 라이브러리
왜씁니까?
state를 선언했는데 이를 어디 저 밑에 있는 자식컴포넌트한테 줘서 쓸일이 있다고 칩시다.
그럼 죄다 props 뚫어줘서 state랑 setState함수 넘겨줘야 되는데 끔찍함.
그래서 state를 전역으로 관리하는게 필요할 때 씀
1. 설치
npm install @reduxjs/toolkit react-redux
2. 개념
알아둬야할 개념 세가지가 있음
- Store : 말그대로 상태를 저장하는곳
- Provider : Store를 리액트 컴포넌트에 전달하는 놈
- Slice : 저장될 상태, Store에 저장됨
- Reducer : Slice의 상태값을 변경하는 함수들, setState 같은놈들이라 생각하면 된다.
3. 사용법
일단 본 내용은 Create-React-App 라이브러리로 프로젝트를 만들었다고 가정
Store생성하기
src/app/store.js에 스토어를 만듭시다. 아래와 같은 코드를 입력해줍니다.
import { configureStore } from '@reduxjs/toolkit'
export default configureStore({
reducer: {}
})
Provider로 나의 리액트 App에 Store전달
보통 프로바이더는 리액트 컴포넌트 최상단에 넣어 놓는게 편합니다. 그래야 모든 컴포넌트들이 스토어를 사용하니깐요.
src/index.js 에 아래와 같이 프로바이더를 전달해줍니다.
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import store from './app/store'
import { Provider } from 'react-redux'
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
Slice 만들기
slice는 전역으로 관리될 state입니다. slice를 만들 때는 다음과 같은 값들을 정의해줘야 합니다.
- name : slice들을 구분짓는 이름
- initialState : state의 초기값
- reducers : state값을 변경해줄 함수들
src/features/counter/counterSlice.js 에 슬라이스 파일을 만들어 봅시다.
import { createSlice } from '@reduxjs/toolkit'
export const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0
},
reducers: {
increment: state => {
// Redux Toolkit allows us to write "mutating" logic in reducers. It
// doesn't actually mutate the state because it uses the Immer library,
// which detects changes to a "draft state" and produces a brand new
// immutable state based off those changes
state.value += 1
},
decrement: state => {
state.value -= 1
},
incrementByAmount: (state, action) => {
state.value += action.payload
}
}
})
// Action creators are generated for each case reducer function
export const { increment, decrement, incrementByAmount } = counterSlice.actions
export default counterSlice.reducer
여기서 아래와 같은 궁금증이 들 수 있음
어라 리듀서 함수들을 보니 state를 바꾸는 함수를 미리 정의하네요? 불편하게 왜 그럼? 걍 setState로 값 내맘대로 넣으면 안됨?
개발자 피셜 setState로 내가 원하는 값 손쉽게 변경하면 편하긴 한데, 버그가 생길경우 디버깅이 힘들다 함.
그래서 값을 update하는 함수를 미리 정의하면 좀 불편하지만 버그 추적이 쉬워서 저리 만든듯
Slice를 Store에 붙여주기
store에 slice를 붙여주려면 slice의 reducer 파라미터를 사용하면 된다. 위 코드에서 counterSlice.reducer를 export한걸 import 하여 스토어에 붙여주자
app/store.js
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from '../features/counter/counterSlice'
export default configureStore({
reducer: {
counter: counterReducer
}
})
본격적으로 state 사용하기
다음 두가지만 기억하면 된다
- useSelector : store에 저장된 state를 가져오는 hook
- useDispatch : state를 변경하기 위해 reducer를 호출하는 함수
useSelector는 다음과 같은 형태로 사용한다.
useSelector(state.스토어에 저장된 state.value);
useDispatch는 다음과 같은 형태로 사용한다
const dispatch = useDispatch();
dispatch(state값을 변경할 reducer함수());
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'
import styles from './Counter.module.css'
export function Counter() {
const count = useSelector(state => state.counter.value)
const dispatch = useDispatch()
return (
<div>
<div>
<button
aria-label="Increment value"
onClick={() => dispatch(increment())}
>
Increment
</button>
<span>{count}</span>
<button
aria-label="Decrement value"
onClick={() => dispatch(decrement())}
>
Decrement
</button>
</div>
</div>
)
}
잠깐만요. 저 위에 increamentByAmount는 setState같이 쓰는 함수인거 같은데 어케 쓰나요?
요거요?
incrementByAmount: (state, action) => {
state.value += action.payload
}
이렇게 쓰시면 됩니다.
dispatch(incrementByAmount(10));
그럼 10이 action.payload로 값이 넘어옵니다.
'React' 카테고리의 다른 글
이벤트 버블링과 캡처링 (0) | 2022.11.17 |
---|---|
리액트에서 특정페이지 스크롤 막기 (0) | 2022.11.16 |
Framer 애니메이션 배우기 (0) | 2022.11.01 |
Cannot find file does not match the corresponding name on disk (0) | 2022.09.21 |
useHref() may be used only in the context of a <Router> component. (0) | 2022.09.19 |
댓글