노력이 좋아서
<step82>'redux(react)_고객관리 사이트_redux로 구현'
zoaseo
2022. 7. 18. 09:12
2022.07.08 - [공부가 좋아서] - 'react_고객관리 사이트 구현_step_final'
<step76>'react_고객관리 사이트 구현_step_final'
1) green_customer_client components/ CreateCustomer.js import React, { useState } from 'react'; import { Table, TableBody, TableRow, TableCell } from '@mui/material'; import PopupDom from './PopupD..
zoaseo.tistory.com
1)
components/
components/CreateCustomerContainer.js
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { setInput, setSubmit, goToHome } from '../modules/customers';
import CreateCustomer2 from './CreateCustomer2';
import { useNavigate } from 'react-router-dom';
const CreateCustomerContainer = () => {
const addCustomer = useSelector(state=>state.customers.addCustomer);
const dispatch = useDispatch();
const navigate = useNavigate();
const onHome = () => {
dispatch(goToHome(navigate));
}
const onChange = (e) => {
dispatch(setInput(e));
}
const onSubmit = () => {
dispatch(setSubmit());
}
return (
<div>
<CreateCustomer2 onHome={onHome} onChange={onChange} onSubmit={onSubmit} addCustomer={addCustomer}/>
</div>
);
};
export default CreateCustomerContainer;
components/CreateCustomer2.js
import React, { useState } from 'react';
import { Table, TableBody, TableRow, TableCell } from '@mui/material';
import PopupDom from './PopupDom';
import PopupPostCode from './PopupPostCode';
const CreateCustomer2 = ({ onChange, onSubmit, addCustomer, onHome }) => {
// 우편번호 관리하기
const onAddData = (data) => {
console.log(data);
const postAD = data.address;
onChange({
target: {
name: 'c_add',
value: postAD
}
})
}
// 팝업창 상태 관리
const [ isPopupOpen, setIsPopupOpen] = useState(false);
// 팝업창 상태 true로 변경
const openPostCode = () => {
setIsPopupOpen(true);
}
// 팝업창 상태 false로 변경
const closePostCode = () => {
setIsPopupOpen(false);
}
// 폼 submit 이벤트
const onSubmitch = (e) => {
// form에 원래 연결된 이벤트를 제거
e.preventDefault();
// 전화번호가 숫자인지 체크하기
if(isNaN(addCustomer.c_phone)){
alert("전화번호는 숫자만 입력해주세요");
}
// input에 값이 있는지 체크하고
// 입력이 다되어있으면 post전송
else if(addCustomer.c_name !== "" && addCustomer.c_phone !== "" &&
addCustomer.c_birth !== "" && addCustomer.c_gender !== "" &&
addCustomer.c_add !== "" && addCustomer.c_adddetail !== ""){
onSubmit();
onHome();
}
}
return (
<div>
<h2>신규 고객 등록하기</h2>
<form onSubmit={onSubmitch}>
<Table>
<TableBody>
<TableRow>
<TableCell>이름</TableCell>
<TableCell>
<input name="c_name" type="text"
value={addCustomer.c_name}
onChange={onChange}/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>연락처</TableCell>
<TableCell>
<input name="c_phone" type="text"
value={addCustomer.c_phone}
onChange={onChange}/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>생년월일</TableCell>
<TableCell>
<input name="c_birth" type="date"
value={addCustomer.c_birth}
onChange={onChange}/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>성별</TableCell>
<TableCell>
여성<input name="c_gender" type="radio"
value="여성"
onChange={onChange}/>
남성<input name="c_gender" type="radio"
value="남성"
onChange={onChange}/>
</TableCell>
</TableRow>
<TableRow>
<TableCell>주소</TableCell>
<TableCell>
<input name="c_add" type="text"
value={addCustomer.c_add}
onChange={onChange}/>
<input name="c_adddetail" type="text"
value={addCustomer.c_adddetail}
onChange={onChange}/>
<button type="button" onClick={openPostCode}>우편번호 검색</button>
<div id="popupDom">
{isPopupOpen && (
<PopupDom>
<PopupPostCode onClose={closePostCode}
onAddData={onAddData}/>
</PopupDom>
)}
</div>
</TableCell>
</TableRow>
<TableRow>
<TableCell colSpan={2}>
<button type="submit">등록</button>
<button type="reset">취소</button>
</TableCell>
</TableRow>
</TableBody>
</Table>
</form>
</div>
);
};
export default CreateCustomer2;
components/CustomerContainer.js
import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { getCustomers } from '../modules/customers';
import CustomerUi from './CustomerUi';
const CustomerContainer = () => {
const { data, loading, error } = useSelector(state => state.customers.customers);
const dispatch = useDispatch();
// 컴포넌트 마운트 후 고객 목록 요청
useEffect(()=>{
dispatch(getCustomers());
},[dispatch]);
if(loading) return <div>로딩중입니다.</div>
if(error) return <div>에러가 발생했습니다.</div>
if(!data) return null;
return (
<div>
<CustomerUi customers={data}/>
</div>
);
};
export default CustomerContainer;
components/CustomerUi.js
import React from 'react';
import { Table, TableBody, TableHead, TableCell, TableRow} from '@mui/material';
import Customer from './Customer';
const CustomerUi = ({customers}) => {
return (
<div>
<h2>고객리스트</h2>
<Table>
<TableHead>
<TableRow>
<TableCell>번호</TableCell>
<TableCell>이름</TableCell>
<TableCell>연락처</TableCell>
<TableCell>생년월일</TableCell>
<TableCell>성별</TableCell>
<TableCell>주소</TableCell>
</TableRow>
</TableHead>
<TableBody>
{customers.map(customer=>(
<Customer key={customer.no} customer={customer}/>
))}
</TableBody>
</Table>
</div>
);
};
export default CustomerUi;
modules/
modules/customers.js
import axios from 'axios';
import { API_URL } from '../config/conf';
// 리덕스 액션타입, 초깃값, 액션생성함수, 리듀서
const GET_CUSTOMERS = "GET_CUSTOMERS";
const GET_CUSTOMERS_ERROR = "GET_CUSTOMERS_ERROR";
const GET_CUSTOMERS_SUCCESS = "GET_CUSTOMERS_SUCCESS";
const SET_INPUT = "SET_INPUT";
const SET_RESET = "SET_RESET";
// 초깃값 설정
const initialState = {
customers: {
loading: false,
data: null,
error: null
},
addCustomer: {
c_name: "",
c_phone: "",
c_birth: "",
c_gender: "",
c_add: "",
c_adddetail: ""
}
}
// 액션생성함수
export const setInput = (e) => {
const { name, value } = e.target;
return {
type: SET_INPUT,
name,
value
}
}
// 홈으로 이동 함수
export const goToHome = (navigate) => {
navigate('/');
}
// thunk 함수를 사용해서 액션객체 디스패치하기
export const getCustomers = () => async dispatch => {
dispatch({type:GET_CUSTOMERS}) // 요청시작
try {
const response = await axios.get(`${API_URL}/customers`);
const customers = response.data;
dispatch({type: GET_CUSTOMERS_SUCCESS, customers});
}
catch(e) {
dispatch({type: GET_CUSTOMERS_ERROR, error:e});
}
}
export const setSubmit = () => async (dispatch, getState) => {
const formdata = getState().customers.addCustomer;
try {
const response = await axios.post(`${API_URL}/addCustomer`, formdata);
dispatch({type: SET_RESET})
}
catch(e) {
dispatch({type: SET_RESET})
}
}
// 리듀서 만들기
export default function customers(state = initialState, action){
switch(action.type){
case GET_CUSTOMERS:
return {
...state,
customers: {
loading: false,
data: null,
error: null
}
}
case GET_CUSTOMERS_SUCCESS:
return {
...state,
customers: {
loading: false,
data: action.customers,
error: null
}
}
case GET_CUSTOMERS_ERROR:
return {
...state,
customers: {
loading: false,
data: null,
error: action.error
}
}
case SET_INPUT:
return {
...state,
addCustomer: {
...state.addCustomer,
[action.name]: action.value
}
}
case SET_RESET:
return {
...state,
addCustomer: {
...state.addCustomer,
c_name: "",
c_phone: "",
c_birth: "",
c_gender: "",
c_add: "",
c_adddetail: ""
}
}
default:
return state;
}
}
modules/index.js
import { combineReducers } from "redux";
import customers from "./customers";
const rootReducer = combineReducers({ customers });
export default rootReducer;
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';
import { applyMiddleware, legacy_createStore as createStore } from 'redux';
import rootReducer from './modules';
import { composeWithDevTools } from 'redux-devtools-extension';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(thunk)));
console.log(store.getState());
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
</BrowserRouter>
);
// 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();