dudd
dudd

Reputation: 372

React-Redux problem with update operation

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

Answers (1)

robert
robert

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

Related Questions