2022. 3. 10. 09:29ㆍTechnology[Front]
이전 프로젝트 후기에서 앞으로 쓰면 좋겠다는 기술 중 Redux를 이번 게시글에서 사용해보고자 합니다. 환경은 React에서 사용하고 이에 따라 일반적인 Redux가 아니라 React-Redux를 사용하고자 합니다.
(1) index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { createStore } from 'redux';
import { Provider, useSelector, useDispatch, connect } from 'react-redux';
import { persistStore, persistReducer } from 'redux-persist';
import { PersistGate } from 'redux-persist/integration/react';
import storage from 'redux-persist/lib/storage/session';
function reducer(currentState, action) {
if (currentState === undefined) {
return {
login : {},
board : [],
}
}
const newState = { ...currentState };
if (action.type === "login") {
let login = {
loginUserKey : action.data.userKey,
loginUserId : action.data.user_id,
loginUserPw : action.data.user_pw,
loginUserName : action.data.user_name,
loginUserPhone : action.data.user_phone,
loginUserGrade : action.data.user_level,
}
newState.login = login;
}
else if(action.type === "free") {
let board = [];
action.data.forEach(e => {
if(e.imageKey){
let board_1 = {
postKey : e.postKey.postKey,
postTitle : e.postKey.postTitle,
postText : e.postKey.post_text,
post_view : e.postKey.post_view,
post_date : e.postKey.post_date,
post_topic : e.postKey.post_topic,
post_score : e.postKey.post_score,
user : e.postKey.userKey,
companyKey: e.companyKey,
imageKey: e.imageKey,
image_url: e.image_url,
}
board.push(board_1);
}
else{
let board_1 = {
postKey : e.postKey,
postTitle : e.postTitle,
postText : e.post_text,
post_view : e.post_view,
post_date : e.post_date,
post_topic : e.post_topic,
post_score : e.post_score,
user : e.userKey,
companyKey: null,
imageKey: null,
image_url: null,
}
board.push(board_1);
}
})
newState.board = board;
}
else if (action.type === "logout") {
newState.login = {};
}
return newState;
}
const persistConfig = {
key: 'root',
storage: storage
}
const persistedReducer = persistReducer(persistConfig, reducer);
const store = createStore(persistedReducer);
const persistor = persistStore(store);
ReactDOM.render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<BrowserRouter>
<App />
</BrowserRouter>
</PersistGate>
</Provider>,
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();
위의 코드는 실제 프로젝트에서 일부 발췌한 것으로 사용시 일부 수정해서 사용하시면 됩니다. redux, react-redux, redux-persist를 npm install을 이용해 설치 후 import해서 사용하고 reducer를 정의합니다. reducer란 추후 저장소의 데이터를 업데이트하고자 할 때 reducer를 통해 저장소로 접근하게 되고 접근할 때 action.type을 지정하여 특정 action.type일 때 수행할 작업을 분리할 수 있습니다. currentState가 undefined일 경우 처음 reducer가 실행된 상태이므로 login과 board라는 객체/배열을 초기화합니다. 이후 데이터를 업데이트 할 때에는 우선 기존의 currentState를 모두 가져온 newState에서 각 action.type에 따라 login과 board 객체/배열을 필요에 맞게 생성 후 newState에서의 객체에 대입한 후 return하면 기존의 currentState는 newState로 바뀌어 저장됩니다. persistConfig는 어떤 저장소에 어떤 키값으로 저장할지를 지정할 수 있는데 storage 변수를 import한 게 session storage이므로 앞으로의 redux 정보는 모두 session에 저장됩니다. 이후 store과 persistor를 정의한 후 render에서 반드시 <App />을 <Provider>과 <PersistGate>로 감싸서 실행합니다. <BrowserRouter>의 경우 route를 사용하기 위한 작업이므로 redux와는 무관합니다. 이 때 Provider에 store을 props로 전달하여 항상 store가 공유될 수 있도록 지정하고 PersistGate에도 props로 persistor을 전달하여 항상 store의 정보가 유지될 수 있도록 지정합니다.
(2)setData.js
import React, { useState, useEffect } from 'react';
import { useDispatch, useSelector } from "react-redux";
import axios from "axios";
const setData = () => {
let board = useSelector(state => state.board);
//useDispatch => Redux 값 변경
const dispatch = useDispatch();
if(Object.keys(board).length === 0) {
let url = "http://digitalgamenomad.cf:8088/boardshow"; //backend의 데이터 불러오기
axios
.get(url)
.then((response) => {
console.log(response.data);
dispatch( { type: "free", data: response.data } );
});
}
board = useSelector(state => state.board);
return board;
}
export default setData;
위의 코드는 실제 프로젝트에서 일부 발췌한 것으로 사용시 일부 수정해서 사용하시면 됩니다. react-redux에서 useDispatch와 useSelector를 import하고나서 useSelector를 이용해 redux storage에 저장되어 있는 데이터에 접근이 가능합니다. 그래서 state에서 board 배열을 꺼내와서 만약 board의 키 개수가 0이라면(기존에 저장되어 있는 값이 존재하지 않는다면) dispatch를 이용해서 axios에서 받아온 데이터를 action.type은 free로 data는 response.data를 전달하고 있습니다. 해당 action.type에 맞게 앞서 index.js에서 정의한 reducer에서 지정한 수행방식에 따라 작동하고 redux의 storage 데이터를 갱신합니다. 이후 다시 useSelector를 이용해 업데이트 이후의 데이터를 가져오고 해당 데이터를 return 합니다.
만약 기존에 저장된 데이터만 이용하고 업데이트 하고 싶지 않은 경우 useSelector만을 이용해 필요한 객체를 꺼내서 사용하시면 됩니다.
이번 게시글에서는 react-redux를 이용해서 데이터를 모든 컴포넌트에서 공유하고 해당 데이터를 set하고 get하는 방법에 대해 알아보았습니다.
'Technology[Front]' 카테고리의 다른 글
React에서 NaverLogin API를 이용하여 네이버로그인 지원하기 (1) | 2022.03.24 |
---|---|
React 게시글을 react-table을 이용해 정렬, 페이징처리하기 (1) | 2022.03.23 |
3D맵 구현하기 - 미로 만들기 (1) | 2022.03.02 |
3D맵 구현하기 - light 제어하기 (1) | 2022.02.28 |
3D맵 구현하기 - 유리재질 벽 구현하기 (1) | 2022.02.25 |