npm install @material-ui/icons @mui/material @material-ui/core @mui/system
컴포넌트 분리 후 구조
Header.js (상단)
import { AppBar, IconButton, Toolbar, Typography } from '@material-ui/core';
import { Menu as MenuIcon } from "@material-ui/icons";
function Header() {
return (
<AppBar position="static">
<Toolbar variant="dense">
<IconButton edge="start" color="inherit" aria-label="menu" sx={{ mr: 2 }}>
<MenuIcon />
</IconButton>
<Typography variant="h6" color="inherit" component="div">
exoluse-react
</Typography>
</Toolbar>
</AppBar>
)
}
export default Header;
import { Restore as RestoreIcon
, Favorite as FavoriteIcon
, LocationOn as LocationOnIcon } from "@material-ui/icons";
import { Paper, BottomNavigation, BottomNavigationAction } from '@mui/material';
function Bottom() {
return (
<Paper sx={{ position: 'fixed', bottom: 0, left: 0, right: 0 }} elevation={3}>
<BottomNavigation
showLabels
onChange={(event, newValue) => {
// setValue(newValue);
}}
>
<BottomNavigationAction label="Recents" icon={<RestoreIcon />} />
<BottomNavigationAction label="Favorites" icon={<FavoriteIcon />} />
<BottomNavigationAction label="Nearby" icon={<LocationOnIcon />} />
</BottomNavigation>
</Paper>
)
}
export default Bottom;
import {useEffect, useState} from 'react';
import { Link, useHistory } from 'react-router-dom';
import { Add as AddIcon } from "@material-ui/icons";
import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, Fab } from '@mui/material';
import './App.css';
function EmpList() {
let history = useHistory();
let [empList, changeEmpList] = useState([]);
let [refreshComponent, changeRefreshComponent] = useState("");
useEffect( ()=>{
fetch("http://localhost:3001/getEmpList").then(
(response)=>{
return response.json();
}
).then( (response)=>{
changeEmpList(response.data);
} )
}, [ refreshComponent ] );
return (
<>
<TableContainer component={Paper}>
<Table aria-label="simple table">
<TableHead>
<TableRow>
<TableCell align="center">Id</TableCell>
<TableCell align="center">Name</TableCell>
</TableRow>
</TableHead>
<TableBody>
{empList.map((row) => (
<TableRow
key={row.id}
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
>
<TableCell component="th" scope="row" align="center">
{row.id}
</TableCell>
<TableCell align="center">
<Link to={ '/detail/'+row.id }>{row.name}</Link>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
<Link to={ '/insert'}>
<Fab sx={{ position: 'fixed', bottom: 70, right: 10 }} color="primary" aria-label="add">
<AddIcon />
</Fab>
</Link>
</>
)
}
export default EmpList;
import {useEffect, useState} from 'react';
import { useParams, useHistory } from 'react-router-dom';
import { Button } from '@material-ui/core';
import { TextField } from '@mui/material';
import { Box } from '@mui/system';
function EmpDetail() {
let history = useHistory();
let [emp, changeEmp] = useState({});
let parameter = useParams();
let [inputName, changeInputName] = useState("");
useEffect( ()=>{
fetch("http://localhost:3001/getEmpInfo/"+parameter.id).then(
(response)=>{
return response.json();
}
).then( (response)=>{
changeEmp(response.data[0]);
// 값 초기화
changeInputName(response.data[0].name);
} )
}, [ ] );
return (
<>
<Box
component="form"
sx={{
'& > :not(style)': { m: 1, width: '25ch' },
}}
noValidate
autoComplete="off"
>
<TextField id="outlined-basic" value={inputName} label="Input Name" variant="outlined" onChange={ (e)=>{
changeInputName(e.target.value);
} } />
</Box>
<div>
<Button m={2} variant="contained" color="primary" onClick={ ()=>{
fetch("http://localhost:3001/setEmpInfo/"+parameter.id+"/"+inputName).then(
(response)=>{
console.log("success setEmpInfo");
history.push("/react");
}
)
} } >변경!</Button>
<Button m={2} variant="contained" color="error" onClick={ ()=>{
fetch("http://localhost:3001/delEmpInfo/"+parameter.id).then(
(response)=>{
console.log("success delEmpInfo");
history.push("/react");
}
)
} } >삭제!</Button>
<Button variant="contained" color="secondary" onClick={ ()=>{
history.push("/react");
} } >목록으로</Button>
</div>
<hr />
<div>
{inputName} 으로 변경될 예정...
</div>
</>
)
}
export default EmpDetail;
import {useState} from 'react';
import { useHistory } from 'react-router-dom';
import { Button } from '@material-ui/core';
import { TextField } from '@mui/material';
import { Box } from '@mui/system';
function EmpInsert() {
let [inputName, changeInputName] = useState("");
let history = useHistory();
return (
<>
<Box
component="form"
sx={{
'& > :not(style)': { m: 1, width: '25ch' },
}}
noValidate
autoComplete="off"
>
<TextField id="outlined-basic" label="Input Name" variant="outlined" onChange={ (e)=>{
changeInputName(e.target.value);
} } />
</Box>
<Button m={2} variant="contained" color="primary" onClick={ ()=>{
fetch("http://localhost:3001/insEmpInfo/"+inputName).then(
(response)=>{
console.log("success insEmpInfo");
history.push("/react");
}
)
} }>{inputName} 으로 등록!</Button>
<Button variant="contained" color="secondary" onClick={ ()=>{
history.push("/react");}
} >목록으로</Button>
</>
)
}
export default EmpInsert;
컴포넌트를 잘 만들자. 뭔가 익숙해지니 뚝딱 만들어낸다는 느낌도 든다.
잘봤습니다