2가지 방법이 존재
- DB의 data를 실제로 삭제
- DB에서 실제로 data를 삭제하지는 않고, 화면상에서만 삭제
2번의 방법이 많이 사용된다. data를 실제로 삭제해버리면 user가 언제 자신의 정보를 삭제했는지, 언제 가입을 했었는지 등에 대한 정보 역시 추적이 불가능해지기 때문이다.
DB에 isDeleted 속성을 추가하고, DB에서 data를 불러올 때 isDeleted = 0 인 속성만 가져오고, 삭제를 할 떄는 isDeleted = 1 로 설정해준다.
그러나 이번 글에서는 2번처럼 구현을 하지 않고, 1번으로 할 것. ( 실습이기 때문에 1번이 더 편리 )
Components에 CustomerDelete.js 속성을 추가해준다.
const url = '/' + id
이 부분에서{id}
로 붙여줬었는데 그래서 오류가 났었다.
api.delete(url)
후에(then)this.props.stateRefresh()
를 해야 지우고나서 새로고침이 자동으로 된다.
부모 component에서 넘겨준 함수
stateRefresh()
를 사용한다.
onClick
을 했을 때, event가 발생하고 event가 발생했을 때deleteCustomer
를 호출한다.
App.js 에서 동적으로 data를 보내주는 Customer class에
CustomerDelete
를 추가해준다. stateRefresh와 id를 넘겨준다.
TableCell에 삭제를 추가해주고, Cutomer component에 stateRefresh 함수와 id 값으로 userData.idx값을 넘겨준다.
import React, {Component} from 'react';
import logo from './logo.svg';
import './App.css';
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'
import {withStyles} from '@material-ui/core/styles'
import axios from 'axios'
const styles = theme=>({
root:{
width:'100%',
marginTop: theme.spacing.unit*3,
overflowX:"auto"
},
table:{
minWidth:1080
},
progress:{
margin: theme.spacing.unit *2
}
})
const api = axios.create({
baseURL: `/user/test`
})
class App extends Component{
constructor(props){
super(props)
this.state={
dataState:[],
completed:0
}
}
stateRefresh=()=>{
this.setState({
dateState:[],
completed:0
})
this.callApi()
}
componentDidMount(){
this.timer = setInterval(this.progress,20)
this.callApi()
}
callApi = async()=>{
api.get('/').then(res=>{
this.setState({
dataState:res.data.userData
})
})
}
progress = ()=>{
const{ completed } = this.state.completed
this.setState({
completed: completed>=100 ? 0 : completed +1
})
}
render(){
const {classes} = this.props
return (
<div>
<Paper className={classes.root}>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell>번호</TableCell>
<TableCell>이미지</TableCell>
<TableCell>이름</TableCell>
<TableCell>나이</TableCell>
<TableCell>성별</TableCell>
<TableCell>직업</TableCell>
<TableCell>삭제</TableCell>
</TableRow>
</TableHead>
<TableBody>
{
this.state.dataState.map(userData=>{
return(
<Customer
stateRefresh={this.stateRefresh}
img={userData.img}
key={userData.idx}
id={userData.idx}
name={userData.name}
gender={userData.gender}
age={userData.age}
job={userData.job}
/>
)
})
}
</TableBody>
<TableBody>
<input type="button" value="get data" onClick={
function(){
api.get('/').then(res=>{
console.log(res.data.userData)
})
}
}></input>
</TableBody>
</Table>
</Paper>
<CustomerAdd stateRefresh={this.stateRefresh}/>
</div>
);
}
}
export default withStyles(styles)(App);
import React, {Component} from 'react'
import TableRow from '@material-ui/core/TableRow'
import TableCell from '@material-ui/core/TableCell'
import CustomerDelete from './CustomerDelete'
class Customer extends Component{
render(){
return(
<TableRow>
<TableCell>{this.props.id}</TableCell>
<TableCell><img src={this.props.img} alt="profile"/></TableCell>
<TableCell>{this.props.name}</TableCell>
<TableCell>{this.props.age}</TableCell>
<TableCell>{this.props.gender}</TableCell>
<TableCell>{this.props.job}</TableCell>
<TableCell><CustomerDelete stateRefresh={this.props.stateRefresh} id={this.props.id}/></TableCell>
</TableRow>
)
}
}
export default Customer;
import React, {Component} from 'react'
import axios from 'axios'
const api = axios.create({
baseURL: `/user/test`
})
class CustomerAdd extends Component{
constructor(props){
super(props)
this.state={
name:'',
age:'',
gender:'',
job:'',
file:null, // byte형태의 data
fileName:'' // 이미지의 이름
}
}
handleFormSubmit = (e)=>{
e.preventDefault()
this.addCustomer().then(()=>{
this.props.stateRefresh()
})
this.setState({
name:'',
age:'',
gender:'',
job:'',
file:null, // byte형태의 data
fileName:'' // 이미지의 이름
})
}
handleFileChange = (e)=>{
this.setState({
file: e.target.files[0], // e.target = event가 발생한 input값 자체
fileName: e.target.value
})
}
handleValueChange = (e)=>{
let nextState={}
nextState[e.target.name] = e.target.value
this.setState(nextState)
}
addCustomer = async ()=>{
const formData = new FormData();
formData.append('img',this.state.file)
formData.append('name',this.state.name)
formData.append('age',this.state.age)
formData.append('gender',this.state.gender)
formData.append('job',this.state.job)
const config = {
headers:{
'content-type':'multipart/form-data'
}
}
var object = {}
formData.forEach(function(value,key){
object[key]=value
})
console.log(object)
return api.post('/',
formData,config
)
}
render(){
return(
<form onSubmit={this.handleFormSubmit}>
<h1>고객 추가</h1>
프로필 이미지: <input type="file" name="file" file={this.state.file} value={this.state.fileName} onChange={this.handleFileChange}/><br/>
이름: <input type="text" name="name" value={this.state.name} onChange={this.handleValueChange}/><br/>
나이: <input type="text" name="age" value={this.state.age} onChange={this.handleValueChange}/><br/>
성별: <input type="text" name="gender" value={this.state.gender} onChange={this.handleValueChange}/><br/>
직업: <input type="text" name="job" value={this.state.job} onChange={this.handleValueChange}/><br/>
<button type="submit">추가하기</button>
</form>
)
}
}
export default CustomerAdd;
import React, {Component} from 'react'
import axios from 'axios'
const api = axios.create({
baseURL: `/user/test`
})
class CustomerDelete extends Component{
deleteCustomer(id){
const url = '/' + id
api.delete(url).then(()=>{
this.props.stateRefresh()
})
}
render(){
return(
<button onClick={(e)=>{this.deleteCustomer(this.props.id)}}>
삭제
</button>
)
}
}
export default CustomerDelete