22.2.5 (토) +13days
1. Redux
총 3가지 타입의 공식 문서가 존재
- Redux (https://redux.js.org/)
- React Redux (https://react-redux.js.org/)
- React Toolkit (https://redux-toolkit.js.org/)
Getting Started with React Redux
React Redux is the official React UI bindings layer for Redux. It lets your React components read data from a Redux store, and dispatch actions to the store to update state.
API Overview
Provider
React Redux includes a <Provider /> component, which makes the Redux store available to the rest of your app:
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import store from './store'
import App from './App'
const rootElement = document.getElementById('root')
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
rootElement
)
Why Use React Redux?
It is the Official Redux UI Bindings for React
It Implements Performance Optimizations For You
Community Support
Flux
https://reactjs.org/blog/2014/05/06/flux.html
정리1
전역 상태 관리 ⇒ vs 지역 상태 관리
단 방향 데이터(상태) 흐름 ⇒ Flux
구성 요소 ⇒ store / Reducer / Action / Selector
2. Redux Toolkit
The Redux Toolkit package is intended to be the standard way to write Redux logic. It was originally created to help address three common concerns about Redux:
- "Configuring a Redux store is too complicated"
- "I have to add a lot of packages to get Redux to do anything useful"
- "Redux requires too much boilerplate code"
We can't solve every use case, but in the spirit of create-react-app and apollo-boost, we can try to provide some tools that abstract over the setup process and handle the most common use cases, as well as include some useful utilities that will let the user simplify their application code.
Redux Toolkit also includes a powerful data fetching and caching capability that we've dubbed "RTK Query". It's included in the package as a separate set of entry points. It's optional, but can eliminate the need to hand-write data fetching logic yourself.
These tools should be beneficial to all Redux users. Whether you're a brand new Redux user setting up your first project, or an experienced user who wants to simplify an existing application, Redux Toolkit can help you make your Redux code better.
Code Sample
import Counter from "./features/counter/Counter";
function App() {
return (
<div className="App">
<Counter />
</div>
);
}
export default App;
fetch-msw/src/App.js
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "../features/counter/counterSlice";
export default configureStore({
reducer: { counter: counterReducer },
});
fetch-msw/src/app/store.js
import React from "react";
import { useDispatch, useSelector } from "react-redux";
import { decrement, increment, incrementByAmount } from "./counterSlice";
export default function Counter() {
const count = useSelector((state) => state.counter.value);
const dispatch = useDispatch();
return (
<div>
<button onClick={() => dispatch(increment())}>Increment</button>
<span>{count}</span>
<button onClick={() => dispatch(decrement())}>Decrement</button>
<button onClick={() => dispatch(incrementByAmount(5))}>+5</button>
</div>
);
}
fetch-msw/src/features/counter/Counter.jsx
정리2
RTK(Redux Toolkit) ⇒ Redux 라이브러리들의 조합
라이브러리들 ⇒ immer / saga / thunk / reselect
Redux Dex Tools ⇒ Chrome extention
3. API & DataFectch
API, Data Fetch와 관련된 내용을 보기 전에 먼저 Redux 공식 문서의 Hooks를 살펴본다. 기본적으로 useSelector와 useDispatch 정도를 자주 사용하게 된다.
Hooks
https://react-redux.js.org/api/hooks
useSelector, useDispatch를 자주 사용하게 된다.
데이터 페칭과 상태 관리의 분리
데이터 페칭과 상태관리의 역할이 분리되면서 Redux 또한 데이터 페칭의 목적에 맞는 라이브러리를 RTK를 통해 제공하고 있다.
RTK Query Overview
https://redux-toolkit.js.org/rtk-query/overview
WHAT YOU'LL LEARN
- What RTK Query is and what problems it solves
- What APIs are included in RTK Query
- Basic RTK Query usage
Redux Async Login and Data Fetching (RTK 아님)
리덕스로만 비동기 로직을 처리할 때는 dispatch된 이벤트를 미들웨어에서 통해 API를 갔다온 후 reducer의 값이 변경되는 프로세스였다.
createAsyncThunk
https://redux-toolkit.js.org/api/createAsyncThunk
RTK에서는 createAsyncThunk를 활용해 비동기 작업을 처리할 수 있다.
counterSllice 파일에 비동기 처리를 위한 fetchIncrement 코드를 추가해준다. 그리고 extraReducers에 처리할 코드를 작성한다.
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import axios from "axios";
export const fetchIncrement = createAsyncThunk(
"counter/fetchIncrement",
async (value) => {
const response = await axios.put("/counter/increment", { value: value });
return response.data;
}
);
export const counterSlice = createSlice({
name: "counter",
initialState: {
value: 0,
},
reducers: {
increment: (state) => {
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
incrementByAmount: (state, action) => {
state.value += action.payload;
},
},
extraReducers: {
[fetchIncrement.fulfilled]: (state, action) => {
state.value = action.payload.value;
},
},
});
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;
fetch-msw/src/features/counter/counterSlice.js
버튼은 fetchIncrement를 dispatch에 매개변수를 포함해 전달한다.
import React from "react";
import { useDispatch, useSelector } from "react-redux";
import {
decrement,
increment,
incrementByAmount,
fetchIncrement,
} from "./counterSlice";
export default function Counter() {
const count = useSelector((state) => state.counter.value);
const dispatch = useDispatch();
return (
<div>
<button onClick={() => dispatch(increment())}>Increment</button>
<button onClick={() => dispatch(fetchIncrement(count))}>
Fetch Increment
</button>
<span>{count}</span>
<button onClick={() => dispatch(decrement())}>Decrement</button>
<button onClick={() => dispatch(incrementByAmount(5))}>+5</button>
</div>
);
}
msw에서 URL을 가져와 모킹 처리한다.
import { rest } from "msw";
export const handlers = [
rest.put("http://localhost:3000/counter/increment", async (req, res, ctx) => {
const { value } = req.body;
return res(ctx.json({ value: value + 2 }));
}),
];
정리3
Hooks ⇒ useSelector / useDispatch
API통신 ⇒ 비동기 작업 (RTK-Query)
Redux-Thunk ⇒ Action으로 API 요청/결과 Store에 반영
본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다
댓글