오늘도 코딩하나
[React] nodejs + mysql 연동 (2) Router, Redux-toolkit 사용하는 경우 본문
기본적인 mysql 연동에 대한 내용은 하단 내용을 참고하길 바란다.
https://coding-hana.tistory.com/49
1. 서버 설정
- server.js
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, '../account/build', 'index.html'));
})
(React) index.html - 여러 페이지 렌더링
→ 모든 경로에 대해 index.html 반환하도록 설정하여, React Router가 클라이언트 측에서 라우팅 관리
(Server) 기본적으로 정적 파일만 서빙하고,
'GET /about', 'GET /contact'와 같은 요청에 대해 서버에서 해당 경로를 처리하지 않기 때문에 404 오류 반환
* API 경로가 해당 소스보다 상위에 있어야 한다.
2. Redux-tookit 설정
- dataSlice.js
import { configureStore, createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import axios from 'axios';
// MySQL에서 데이터 가져오기
export const fetchData = createAsyncThunk('list/fetchData', async () => {
const response = await axios.get('http://localhost:8009/list');
return response.data;
});
// MySQL에서 데이터 저장하기
export const saveData = createAsyncThunk('list/insert', async (data) => {
const response = await axios.post('http://localhost:8009/list/insert', data);
return response.data;
});
let listData = createSlice({
name: 'listData',
initialState : {
items : [],
status: 'idle',
error: null,
},
extraReducers: (builder) => {
builder
.addCase(fetchData.pending, (state) => {
state.status = 'loading'
})
.addCase(fetchData.fulfilled, (state, action) => {
state.status = 'succeeded';
state.items = action.payload;
})
.addCase(fetchData.rejected, (state, action) => {
state.status = 'failed'
state.items = action.error.message;
})
.addCase(saveData.fulfilled, (state, action) => {
state.items = action.payload
})
}
})
export default configureStore({
reducer: {
listData : listData.reducer
}
})
▷ status : idle(요청이 시작되지 않음) / loading(요청이 진행 중) / succeeded(요청 성공) / failed(요청 실패)
- App.js
const listData = useSelector((state) => state.listData.items);
const payListStatus = useSelector((state) => state.listData.status);
useEffect(() => {
if(payListStatus === 'idle') {
dispatch(fetchData());
}
}, [payListStatus, dispatch]);
const addData = () => {
dispatch(saveData({name, age}));
}
return (
<div className="App">
<h1>React MySQL 연동</h1>
{payListStatus === 'loading' && <div>Loading...</div>}
{payListStatus === 'succeeded' && (
<ul>
{Array.isArray(data) && data.map(item => (
<li key={item.id}>{item.name} - {item.age}</li>
))}
</ul>
)}
{payListStatus === 'failed' && (
<div>Fail!</div>
)}
<input type="text" placeholder="이름을 입력하세요." value={name} onChange={e => setName(e.target.value)} />
<input type="text" placeholder="나이를 입력하세요." value={age} onChange={e => setAge(e.target.value)} />
<button onClick={addData}>Add Data</button>
</div>
)
▶ createAsyncThunk & extraReducer
Redux toolkit에서 비동기 작업을 보다 쉽게 처리하고 상태를 관리할 수 있도록 제공하는 기능
- createAsyncThunk : 비동기 처리를 할 액션 정의
- extraReducer : 비동기 액션의 결과를 처리하여 상태 변경 로직 정의
* extraReducer vs reducer
- reducers : 동기적 / action creator을 자동으로 toolkit이 만들어줌
- extraReducers : 비동기적 / action creator을 자동으로 만들지 못함
→ slice의 extraReducers에 직접 action creator 정의
'React' 카테고리의 다른 글
[React] nodejs + mysql 연동 (1) (0) | 2024.09.04 |
---|---|
[React] 일반적인 setState 사용 vs setState 콜백 함수 (0) | 2024.08.31 |
CSR, SSR, SSG 정리 (0) | 2024.05.27 |