redux(리덕스)는 상태관리 라이브러리라고 할수 있습니다.
react에서는 props라는것이 있고 state라는 것이있습니다.
props는 properties의 줄임말로 컴포넌트 간에 무언가를 주고 받을때 이용합니다.
또한 부모컴포넌트에서 자식컴포넌트로 줄때만 이용할수 있습니다.
만약 부모 컴포넌트에서 자식컴포넌트로 1이라는 것을 준다면 자식컴포넌트에서는 그 1을 변경할수 없습니다.
이 1을 변경하고 싶다면 부모컴포넌트에서 다시 전달을 해주어야만 합니다.
state는 부모컴포넌트에서 자식컴포넌트로 주는 건이 아니라 컴포넌트 안에서 데이터를 교환하거나 전달하기위해 사용합니다.
state는 mutable 속성으로 변경을 할수 있습니다.
만약 2라는 것이 3으로 변경된다면 리랜더링 되는 성격도 가지고 있습니다.
리덕스를 사용할때와 사용하지 않을때를 비교하여 보여주는 그림인데 리덕스를 사용하지 않을때는 데이터가 뭔가 주구난방으로 전달이 됩니다.
하지만 리덕스를 사용하면 깔끔한 데이터 전달이 가능해지는것을 볼 수 있습니다.
리덕스는 컴포넌트부터 시작해여 Dispatch가 되면 Action으로가고 action에서 reducer로 가게되고 store로가게됩니다.
stroe에서 subscribe이 되면 다시 컴포넌트로 가게 되는데요.
리덕스의 데이터 흐름은 한방향으로만 흐른다는 의미의 strict unidirectional data flow입니다.
Action의 역할을 한번 보겠습니다.
액션은 객체형대로 구성이 되어있는데 무었이 일어났는지 설명해주는 객체입니다.
{ type: 'LIKE_ARTICLE', articleID: 42 }는 타입이 라이크아티클인데 아티클이 42번이 되었습니다.
즉 좋아요버튼이 42번 눌렸다는 의미입니다.
{ type: 'FETCH_USER_SUCCESS', response: { id: 3, name: 'Many' } }
는 유저를 가져오는 것을 성공했는데 해당 유저의 id는 3이고 이름은 many입니다.
마지막으로 {type: 'ADD_TODO', text: 'Read the Redux docs.' }의 의미는 리덕스 문서를 읽는다는 것을 투두리스트에 넣는다는 의미가 되겠네요.
이렇듯 상태를 알려주는 것입니다.
리듀서의 경우는 State는 mutable속성으로 변할 수 있었습니다.
만약 3이었던 State가 Action을 함으로 인해서 4로 변했다면 Reducer에서 이러한 것을 알려줍니다.
Store의 경우 어플리케이션에 state를 감싸주는 역할을 합니다.
또 스토어 안에는 여러가지 메서드가 있는데 이 메서드를 활용하여 state를 관리해줄수 있습니다.
이렇게 간단하게 리덕스의 개념을 살펴보았는데 이제 직접 설치를 해보고 설정해볼까요?
npm install redux react-redux redux-promise redux-thunk --save
client 디렉터리 안에 설치를 할건데 이렇게 4가지 디펜던시를 한번에 다운받겠습니다.
reduc-promise와 reduc-thunk는 리덕스 미들웨어인데 이 두개지가 필요한 이유는 리덕스를 더 효율적으로 쓸수 있도록 도와주기 위해서입니다.
리덕스 Store안에서 모든 State를 관리하게 되는데 이 Store를 변경하고 싶다면 Dispatch를해서 Action으로 변경을 시키는 것입니다.
Action은 객체형식이여야 Store가 받을수가 있습니다.
하지만 Store는 언제나 객체형식으로된 Action만 받는것이 아니라 가끔은 promise형식으로 된 것을 받을수도 있고 가끔은 function 형태로 된 것도 받을 때가 있습니다.
하지만 redux store는 객체형식으로만 받을수 있다고 했는데 만약 promise 형식으로 오거나 function 형식으로 오면 store가 받지 못하기 때문에 미들웨어를 다운받아서 store를 도와주는 것입니다.
redux-thunk의 경우는 dispatch한테 어떻게 function을 받는지는 알려주는 역할을 하고 redux-promise는 어떻게 promise를 받을지 알려주는 역할을 합니다.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { Provider } from 'react-redux';
import 'antd/dist/antd.css';
import { applyMiddleware, createStore } from 'redux';
import promiseMiddleware from 'redux-promise';
import ReduxThunk from 'redux-thunk';
import Reducer from './_reducers';
const createStoreWithMiddleware = applyMiddleware(promiseMiddleware, ReduxThunk)(createStore);
ReactDOM.render(
<React.StrictMode>
<Provider
store={createStoreWithMiddleware(Reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__()
)}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
index.js 파일에 이처럼 코드를 작성했습니다.
하나하나 차근차근 설명을 하자만 Procider 태그로 <App /> 태그를 감싸줍니다.
ReactDOM.render(
<React.StrictMode>
<Provider
store={}
>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
그리고 Provider에는 store태그가 있어야하는데요.
import { applyMiddleware, createStore } from 'redux';
import ReduxThunk from 'redux-thunk';
import Reducer from './_reducers';
const createStoreWithMiddleware = applyMiddleware(promiseMiddleware, ReduxThunk)(createStore);
ReactDOM.render(
<React.StrictMode>
<Provider
store={createStoreWithMiddleware(Reducer)}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
설치했던 미들웨어를 사용하기 위해 createStoreWithMiddleware를 선언하고 applyMiddleware로 promiseMiddleware와 ReduxThunk를 넣겠습니다.
그리고 createStore도 사용할 예정입니다.
근데 createStoreWithMiddleware에 Reducer가 뭐냐구요??
아직 안만들어 뒀는데 _reducers 폴더안에 index.js파일을 하나 만들겠습니다.
import { combineReducers } from "redux";
// import user from './user_reducer';
const rootReducer = combineReducers({
// user,
})
export default rootReducer;
아직 기능은 구현하지 않았으니 코드의 형태만 만들어두고 주석처리를 해두겠습니다.
redux extension을 설치해서 리덕스 이용하여 툴을 사용할 예정입니다.
ReactDOM.render(
<React.StrictMode>
<Provider
store={createStoreWithMiddleware(Reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__()
)}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
그리고 돔 안에다가 이런 코드를 작성해주겠습니다!
(본격 구현은 뒷쪽 포스팅에서...)
'따라하며 배우는 시리즈 > NodeJS & ReactJS Basic' 카테고리의 다른 글
[ReactJS] 로그인 페이지 구현하기 (0) | 2022.09.18 |
---|---|
[ReactJS] class Component & functional Component (0) | 2022.09.17 |
[ReactJS] Antd CSS Framework (0) | 2022.09.15 |
[ReactJS] Concurrently로 클라이언트와 서버 한번에 실행하기 (0) | 2022.09.14 |
[ReactJS] CORS이슈 해결을 위한 Proxy 설정 (0) | 2022.09.13 |