Reputation: 271
Here, I am trying to do an CRUD process. Now, I can add, delete and display data. But, i couldn't update the existing data. I want to update or edit the existing data. I tried different methods, to achieve that, but none works. Please check my code below and let me know, how can i make that.
App Component:
import React, { Component } from 'react';
import { withStyles, Grid } from '@material-ui/core';
import styles from './Style'
import Form from './Form';
import DataList from './DataList';
import Header from '../../components/Header';
class App extends Component {
constructor(props){
super(props);
this.state = {
Datas: [
{id: 0, Name: 'Tony Stark', Occupation: 'Iron Man', Details: 'SuperHero, PlayBoy, Philatherophist' },
{id: 1, Name: 'Steve Rogers', Occupation: 'Captain America', Details: 'Captain, Soldier, SuperHero' },
{id: 2, Name: 'Thor', Occupation: 'God of Thunder', Details: 'SuperHero, God, King' },
],
Name: "",
Occupation: "",
Details: "",
}
}
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value
})
}
handleClick = (e, data) => {
e.preventDefault();
//data.id = Math.random()
let Datas = [...this.state.Datas, {id: Math.random(), Name: this.state.Name, Occupation: this.state.Occupation, Details: this.state.Details}];
this.setState({
Datas
})
this.reset()
}
handleDelete = (id) => {
const Datas = this.state.Datas.filter(data=>{
return data.id !== id
});
this.setState({
Datas
})
};
handleUpdate = (e, id) => {
const index = this.state.Datas.findIndex((data)=>{
return data.id === id
});
const data = Object.assign({}, this.state.Datas[index])
data.Name = e.target.value
data.Occupation = e.target.value
data.Details = e.target.value
const Datas = Object.assign([], this.state.Datas);
Datas[index]= data;
this.setState({
Datas
})
}
reset = () => {
this.setState({
Name: "",
Occupation: "",
Details: ""
})
}
render() {
const { classes } = this.props
const { Name, Occupation, Details, Datas } = this.state
return (
<div>
<Header />
<Grid container >
<Grid item xs = {6}>
<div className={classes.cover}>
<Form
handleChange={this.handleChange}
handleClick={this.handleClick}
Name={Name}
Occupation={Occupation}
Details={Details}
/>
</div>
</Grid>
<Grid item xs = {6}>
<div className={classes.cover}>
<DataList
datas={Datas}
handleDelete={this.handleDelete}
handleUpdate={this.handleUpdate}
/>
</div>
</Grid>
</Grid>
</div>
)
}
}
export default withStyles(styles)(App)
Form Component
import React from 'react';
import { withStyles, TextField, Button } from '@material-ui/core';
import styles from './Style'
const Form = (props) => {
const { classes, Name, Occupation, Details } = props
return (
<div>
<form >
<TextField
type="text"
name="Name"
label="Name"
className={classes.textField}
onChange={props.handleChange}
value={Name}
/>
<TextField
type="text"
name="Occupation"
label="Occupation"
className={classes.textField}
onChange={props.handleChange}
value={Occupation}
/>
<TextField
type="text"
name="Details"
label="Details"
className={classes.textField}
onChange={props.handleChange}
value={Details}
/>
<Button variant="outlined" onClick={props.handleClick} type="submit" className = {classes.button}>Submit</Button>
</form>
</div>
)
}
export default withStyles(styles)(Form)
DataList Component
import React from 'react';
import { withStyles, Card, CardContent, Typography, IconButton} from '@material-ui/core';
import Delete from '@material-ui/icons/DeleteOutlined'
import styles from './Style'
const DataList = (props) => {
const { datas, classes } = props
return (
<div>
{
datas.map((data)=> {
return (
<Card key={data.id} className={classes.card} onClick={(e) => props.handleUpdate(e, data.id)} elevation={1}>
<CardContent>
<IconButton aria-label="Delete" className={classes.delete} onClick={()=>props.handleDelete(data.id)}>
<Delete />
</IconButton>
<Typography variant="h4" className={classes.name}>
{data.Name}
</Typography>
<Typography variant="h6" className={classes.body}>
{data.Occupation}
</Typography>
<Typography variant="body1" className={classes.details}>
{data.Details}
</Typography>
</CardContent>
</Card>
)
})
}
</div>
)
}
export default withStyles(styles)(DataList)
Upvotes: 2
Views: 1770
Reputation: 3774
It should be id and then event ( swap the arguments ). You're expecting a bound function to receive the event as the first argument, whereas it will be the id. Also, you don't need to bind the function to this(BTW which will be undefined) since you defined handleupdate
as an arrow function in App
.
handleUpdate = (id, event) => {
.
.
.
}
OR
you can just simply do
<Card key={data.id} className={classes.card}
onClick={ e => {
props.handleUpdate(e, data.id)
}}
elevation={1}
>
------------ Updated -----------
Here is the Solution -
You can use Id
in your state to track which object is being currently edited and Editing
to track that the form is in editing state for updation. Editing
state is then used to render a save button for edtis rather than a submit.
App.js
import React, { Component } from "react";
import { withStyles, Grid } from "@material-ui/core";
import styles from "./Style";
import Form from "./Form";
import DataList from "./DataList";
class App extends Component {
constructor(props) {
super(props);
this.state = {
Datas: [
{
id: 0,
Name: "Tony Stark",
Occupation: "Iron Man",
Details: "SuperHero, PlayBoy, Philatherophist"
},
{
id: 1,
Name: "Steve Rogers",
Occupation: "Captain America",
Details: "Captain, Soldier, SuperHero"
},
{
id: 2,
Name: "Thor",
Occupation: "God of Thunder",
Details: "SuperHero, God, King"
}
],
Id: "",
Name: "",
Occupation: "",
Details: "",
IsEditing: false
};
}
handleChange = e => {
this.setState({
[e.target.name]: e.target.value
});
};
handleClick = (e, data) => {
e.preventDefault();
//data.id = Math.random()
let Datas = [
...this.state.Datas,
{
id: Math.random(),
Name: this.state.Name,
Occupation: this.state.Occupation,
Details: this.state.Details
}
];
this.setState({
Datas
});
this.reset();
};
handleDelete = id => {
const Datas = this.state.Datas.filter(data => {
return data.id !== id;
});
this.setState({
Datas
});
};
handleUpdate = (e, id) => {
const index = this.state.Datas.findIndex(data => {
return data.id === id;
});
const data = Object.assign({}, this.state.Datas[index]);
this.setState({
Id: data.id,
Name: data.Name,
Occupation: data.Occupation,
Details: data.Details,
IsEditing: true
});
};
saveUpdate = id => {
const newData = this.state.Datas.map(d => {
console.log(id, d.id);
if (d.id === id) {
return {
Name: this.state.Name,
Occupation: this.state.Occupation,
Details: this.state.Details
};
}
return d;
});
this.setState(
{
Datas: newData,
IsEditing: false
},
() => {
this.reset();
}
);
};
reset = () => {
this.setState({
Id: "",
Name: "",
Occupation: "",
Details: ""
});
};
render() {
const { classes } = this.props;
const { Id, Name, Occupation, Details, Datas, IsEditing } = this.state;
return (
<div>
<Grid container>
<Grid item xs={6}>
<div className={classes.cover}>
<Form
handleChange={this.handleChange}
handleClick={this.handleClick}
saveUpdate={this.saveUpdate}
Id={Id}
Name={Name}
Occupation={Occupation}
Details={Details}
Editing={IsEditing}
/>
</div>
</Grid>
<Grid item xs={6}>
<div className={classes.cover}>
<DataList
datas={Datas}
handleDelete={this.handleDelete}
handleUpdate={this.handleUpdate}
/>
</div>
</Grid>
</Grid>
</div>
);
}
}
export default withStyles(styles)(App);
Form.js
import React from "react";
import { withStyles, TextField, Button } from "@material-ui/core";
import styles from "./Style";
const Form = props => {
const { Id, classes, Name, Occupation, Details, Editing } = props;
return (
<div>
<form>
<TextField
type="text"
name="Name"
label="Name"
className={classes.textField}
onChange={props.handleChange}
value={Name}
/>
<TextField
type="text"
name="Occupation"
label="Occupation"
className={classes.textField}
onChange={props.handleChange}
value={Occupation}
/>
<TextField
type="text"
name="Details"
label="Details"
className={classes.textField}
onChange={props.handleChange}
value={Details}
/>
{Editing ? (
<Button
variant="outlined"
onClick={e => {
e.preventDefault();
props.saveUpdate(Id);
}}
type="button"
className={classes.button}
>
Update
</Button>
) : (
<Button
variant="outlined"
onClick={props.handleClick}
type="submit"
className={classes.button}
>
Submit
</Button>
)}
</form>
</div>
);
};
export default withStyles(styles)(Form);
Upvotes: 1