Mi Lugarcito
React & Node.js - 필터 함수를 이용한 고객 검색 기능 구현하기 본문
app.js
import logo from './logo.svg';
import './App.css';
import { Component } from 'react';
import Customer from './components/Customer';
//고객추가양식
import CustomerAdd from './components/CustomerAdd';
import Paper from '@material-ui/core/Paper';
import Table from '@material-ui/core/Table';
import TableHead from '@material-ui/core/TableHead';
import TableBody from '@material-ui/core/TableBody';
import TableRow from '@material-ui/core/TableRow';
import TableCell from '@material-ui/core/TableCell';
//프로그래스바 라이브러리 추가하기
import CircularProgress from '@material-ui/core/CircularProgress';
//cs적용하기
import {withStyles} from '@material-ui/core/styles';
//app bar 적용하기
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import IconButton from '@material-ui/core/IconButton';
import Typography from '@material-ui/core/Typography';
import InputBase from '@material-ui/core/InputBase';
import {fade} from '@material-ui/core/styles/colorManipulator';
import MenuIcon from '@material-ui/icons/Menu';
import SearchIcon from '@material-ui/icons/Search';
const styles=theme=>({
root:{
width:"100%",
//minWidth:1080
//marginTop:ThemeProvider.spacing.unit*3,
//overflowX:"auto"
},
menu:{
marginTop:15,
marginBottom:15,
display:'flex',
justifyContent:'center'
},
paper:{
marginLeft:18,
marginRight:18
},
//프로그래스바
progress: {
margin:theme.spacing(2)
},
tableHead:{
fontSize:'2.0rem'
},
menuButton: {
marginRight: theme.spacing(2),
},
title: {
flexGrow: 1,
display: 'none',
[theme.breakpoints.up('sm')]: {
display: 'block',
},
},
search: {
position: 'relative',
borderRadius: theme.shape.borderRadius,
backgroundColor: fade(theme.palette.common.white, 0.15),
'&:hover': {
backgroundColor: fade(theme.palette.common.white, 0.25),
},
marginLeft: 0,
width: '100%',
[theme.breakpoints.up('sm')]: {
marginLeft: theme.spacing(1),
width: 'auto',
},
},
searchIcon: {
padding: theme.spacing(0, 2),
height: '100%',
position: 'absolute',
pointerEvents: 'none',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
inputRoot: {
color: 'inherit',
},
inputInput: {
padding: theme.spacing(1, 1, 1, 0),
// vertical padding + font size from searchIcon
paddingLeft: `calc(1em + ${theme.spacing(4)}px)`,
transition: theme.transitions.create('width'),
width: '100%',
[theme.breakpoints.up('sm')]: {
width: '12ch',
'&:focus': {
width: '20ch',
},
},
}
});
/*
리액트의 component life cycle을 가지고 있다.
1) constructor()
2) componentWillMount()
3) render()
4) componentDidMount()
// props or state => 변경되는 경우에는 shouldComponentUpdate()함수가 사용되어서 실질적으로 다시 render 함수 불러와서 뷰 갱신한다.
*/
//고객정보를 서버에 접속해서 가져올 수 있도록 해야한다. (데이터가 변경될 수 있음)
//props는 변경될 수 없는 데이터를 명시할때 사용 & state 는 변경될 수 있는 데이터를 명시할 때 사용한다.
class App extends Component{
// state={
// customers : "",
// //프로그래스바
// completed : 0 //퍼센트를 알려주는것
// }
constructor(props){
super(props);
this.state={
customers:'',
completed:0,
//여기도 초기화 시켜줘야함
searchKeyword:''
}
}
stateRefresh =() =>{
//state 초기화 하기
this.setState({
customers:'',
completed:0,
searchKeyword:''
});
this.callApi()
.then(res => this.setState({customers:res}))
.catch(err => console.log(err));
}
//실제 api 서버에 접근하도록 하기 (componentDidMount : 데이터 받아오는 작업)
componentDidMount(){
//프로그래스 바
this.timer=setInterval(this.progress, 20); //0.02초마다 한번씩 프로그래스 함수 실행되도록 설정
//컴포넌트 준비 완료
this.callApi()
.then(res => this.setState({customers:res}))
.catch(err => console.log(err));
}
//api 불러오기 (비동기적 수행)
//const : 변수
callApi = async() =>{
const response = await fetch('/api/customers');//로컬호스트 접근
const body = await response.json();
return body;
}
//프로그래스 애니매이션 효과
progress =() => {
const {completed} =this.state;
this.setState({completed:completed >=100 ? 0 : completed +1});
}
//고객 검색 기능 추가하기
handleValueChange =(e) =>{
let nextState ={};
nextState[e.target.name] = e.target.value;
this.setState(nextState);
}
render(){
const filteredComponents =(data) => {
data=data.filter((c)=>{
return c.name.indexOf(this.state.searchKeyword)>-1;
});
return data.map((c)=>{
return <Customer stateRefresh={this.stateRefresh} key={c.id} id={c.id} image={c.image} name={c.name} birthday={c.birthday} gender={c.gender} job={c.job}/>
});
}
const {classes} =this.props;
//배열형태로 보여줄 항목들 나열하기
const cellList =["번호", "프로필 이미지", "이름", "생년월일", "성별", "직업", "설정"];
return(
<div className={classes.root}>
<AppBar position="static">
<Toolbar>
<IconButton
edge="start"
className={classes.menuButton}
color="inherit"
aria-label="open drawer">
<MenuIcon />
</IconButton>
<Typography className={classes.title} variant="h6" noWrap>
고객 관리 시스템
</Typography>
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<InputBase
placeholder="Search…"
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
name="searchKeyword"
value={this.state.searchKeyword}
onChange={this.handleValueChange}
inputProps={{ 'aria-label': 'search' }}
/>
</div>
</Toolbar>
</AppBar>
<div className={classes.menu}>
<CustomerAdd stateRefresh={this.stateRefresh}/>
</div>
<Paper className={classes.paper}>
<Table className={classes.table}>
<TableHead>
<TableRow>
{cellList.map(c => {
return <TableCell className={classes.TableHead}>{c}</TableCell>
})}
</TableRow>
</TableHead>
<TableBody>
{this.state.customers ?
filteredComponents(this.state.customers) :
<TableRow>
<TableCell colSpan="6" align="center">
<CircularProgress className={classes.progress} variant="determinate" value={this.state.completed}/>
</TableCell>
</TableRow>
}
</TableBody>
</Table>
</Paper>
</div>
);
}
}
export default withStyles(styles)(App);
github.com/dmstlf292/React-Management-Tutorial
'React & Next.js' 카테고리의 다른 글
React & Firebase 로 앱 개발하기 - 내비게이션 바 만들기 (0) | 2021.03.15 |
---|---|
React & Firebase 로 앱 개발하기 - react 앱 개발환경 구축하기 (0) | 2021.03.14 |
React & Node.js - AppBar 및 웹 폰트를 적용하여 디자인 개편하기 (0) | 2021.03.13 |
React & Node.js - Material UI 모달 (modal) 디자인 구현하기 (0) | 2021.03.13 |
React & Node.js - 고객 정보 삭제 기능 구현하기 (0) | 2021.03.13 |