Reputation: 372
I am writing a crud app with react-redux, i have successfully implement read
and add
operation, also i am in half way of update
operation, when i click on edit button, i get data filled in form, only problem with update operation. I am using same form for both update
and add
I am facing problem only dispatching
update data, it showing update data in table.
this is my form.js
file:
import React, { Fragment } from "react"
import { connect } from 'react-redux'
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {name: this.props.selectedData.name, age: this.props.selectedData.age, email: this.props.selectedData.email};
this.onHandleChange = this.onHandleChange.bind(this);
this.submit = this.submit.bind(this);
}
submit(event) {
const data = {
name: this.state.name, age: this.state.age, email: this.state.email
};
this.props.dispatch({type: 'ADD_POST', data})
}
onHandleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
}
componentDidUpdate(prevProps){
if(prevProps.selectedData.email !== this.props.selectedData.email){ //Check on email, because email is unique
this.setState({name: this.props.selectedData.name, age: this.props.selectedData.age, email: this.props.selectedData.email})
}
}
render() {
return (
<form>
<div className="form-group">
<input onChange={(event) => this.onHandleChange(event)} value={this.state.name} name="name" type="text" />
</div>
<div className="form-group">
<input onChange={(event) => this.onHandleChange(event)} value={this.state.age} name="age" type="number"/>
</div>
<div className="form-group">
<input onChange={(event) => this.onHandleChange(event)} value={this.state.email} name="email" type="text"/>
</div>
<button onClick={(event) => this.submit(event)} type="button">
{this.props.isEdit ? 'Update' : 'SAVE' }
</button>
</form>
);
}
}
export default connect(null)(Form);
and this is table.js
file
import React, {Fragment} from "react";
import { connect } from "react-redux";
class Table extends React.Component {
onEdit = (item) => { //Use arrow function to bind `this`
this.props.selectedData(item);
}
render() {
return (
<Fragment>
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Age</th>
<th scope="col">Email</th>
<th>Edit</th>
</tr>
</thead>
<tbody>
{this.props.employees.map((item, index) => (
<tr key={index}>
<td>{item.name}</td>
<td>{item.age}</td>
<td>{item.email}</td>
<td>
<button
type="button"
onClick={() => this.onEdit(item)}>EDIT
</button>
</td>
</tr>
))}
</tbody>
</Fragment>
);
}
}
const mapStateToProps = (state) => ({ employees: state.employees });
export default connect(mapStateToProps)(Table);
and this is my postReducer.js
file:
var initialState = {
employees: [{name: 'jhon', age: '23', email: 'a@a'}, {name: 'doe', age: '24', email: 'b@a'}]
};
var postReducer = (state = initialState, action) => {
switch(action.type) {
case 'ADD_POST':
return {
...state,
employees: [...state.employees, action.data],
};
case 'EDIT_POST':
//return
default:
return state;
}
};
export default postReducer;
and this is App.js
file
import React from "react"
import Table from "./table"
import Form from '../components/form'
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedData: {name: '', age: '', email: ''},
isEdit: false
};
}
selectedData = (item) => {
this.setState({selectedData: item,isEdit:true})
}
render() {
return (
<React.Fragment>
<Form selectedData={this.state.selectedData} isEdit={this.state.isEdit}/>
<table>
<Table selectedData={this.selectedData} />
</table>
</React.Fragment>
);
}
}
export default App;
and this is my index.js
file:
import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import postReducer from '../src/postReducer'
const store = createStore(postReducer)
ReactDOM.render((
<Provider store={store}>
<App />
</Provider>
), document.getElementById('app'))
Everything is working great except update operation, Can anyone help me to achieve update operation? I tried a lot and failed to achieve this.
Upvotes: 0
Views: 70
Reputation: 6152
To be able to edit an employee you need some data that is fixed.
For example employee.id
Based on that you can lookup an employee and make the rest of the properties editable.
I added this inside your postReducer:
case 'EDIT_POST':
return {
...state,
employees: state.employees.map(emp => emp.id === action.data.id ? action.data : emp)
}
Working Stackblitz.
Upvotes: 1