【问题标题】:Edit Form Not Updating编辑表格不更新
【发布时间】:2019-08-21 03:46:16
【问题描述】:

我有一个 React 员工管理应用程序。目前,除了编辑员工之外,我的所有 CRUD 操作都在工作。当您单击编辑按钮时,您将进入编辑表单屏幕,可以输入所有输入选项,并提交编辑表单。在编辑表单中,所有输入字段都以状态显示,但提交时,没有任何更新。 https://github.com/PaperPlanes1623/react-employees

App.js

import React, { Component } from 'react';
import Employees from './components/employee/Employees';
import EmployeeForm from './components/employee/EmployeeForm';
import index from './styles/index.scss';


class App extends Component {
  state = {
    employees: [
      { id: 1, firstName: 'Bob', lastName: 'Jones', email: 
'bob@email.com', phone: '801-555-5555' },
      { id: 2, firstName: 'John', lastName: 'Doe', email: 
'john@email.com', phone: '801-655-5555' },
      { id: 3, firstName: 'Mary', lastName: 'Jane', email: 
'mary@email.com', phone: '801-755-5555' }
    ]
  }

  toggleEdit = () => this.setState({ editing: !this.state.editing });

  editEmployee = (employeeData, id) => {
    const employees = this.state.employees.map(employee => {
      if (employee.id === employeeData.id)
        return employeeData;
      return employee
    });
    this.setState({ employees })
  }

  getId = () => {
    // create unique id's
    return Math.floor((1 + Math.random()) * 0x10000)
      .toString(16)
      .substring(1);
  };

  addEmployee = (employeeData) => {
    let newEmployee = { id: this.getId(), ...employeeData }
    this.setState({ employees: [newEmployee, 
...this.state.employees] })
  }

  removeEmployee = (id) => {
    const employees = this.state.employees.filter(employee => {
      if (employee.id !== id)
        return employee
    })
    this.setState({ employees: [...employees] })
  }

  render() {
    const { employees } = this.state
    return (
      <>
        <div class="head">
          Employee Management System
        </div>
        <EmployeeForm add={this.addEmployee} update= . 
       {this.editEmployee} />
        <div class="emp-header">
          All Employees
        </div>
        <Employees employees={employees} remove= . 
   {this.removeEmployee} update={this.editEmployee} edit= . 
   {this.toggleEdit} />
      </>
    )
  }
}




export default App;

EditForm.js

import React, { Component } from 'react';
import { Link } from 'react-router-dom';

class EditForm extends Component {

  state = { firstName: '', lastName: '', phone: '', email: '' };

  componentDidMount() {
    if (this.props.id)
      this.setState({
        firstName: this.props.firstName, lastName: 
this.props.lastName,
        phone: this.props.phone, email: this.props.email
      })
  }

  handleSubmit = (e) => {
    e.preventDefault();
    if (this.props.id) {
      this.props.update(this.state, this.props.id)
    } else {
      this.props.add(this.state)
    }
    this.setState({ firstname: '', lastName: '', phone: '', email: 
'' })
  }


  handleChange = (e) => {
    this.setState({ [e.target.name]: e.target.value })
  }

  render() {
    return (
      <>
        <h1><strong>Edit Employee</strong></h1>
        <form onSubmit={this.handleSubmit}>
          <input
            placeholder="First Name"
            name="firstName"
            value={this.state.firstName}
            onChange={this.handleChange}
          /><br /><br />
          <input
            placeholder="Last Name"
            name="lastName"
            value={this.state.lastName}
            onChange={this.handleChange}
          /><br /><br />
          <input
            placeholder="phone"
            name="phone"
            value={this.state.phone}
            onChange={this.handleChange}
          /><br /><br />
          <input
           placeholder="email"
            name="email"
            value={this.state.email}
            onChange={this.handleChange}
          /><br /><br />
          <Link to='/'>
            <input type="Submit" />
          </Link>
        </form>

      </>
    )
  }
}

export default EditForm;

Main.js

import React, { Fragment } from 'react';
import { Route, Switch } from 'react-router-dom';
import App from './App';
import EditForm from './components/employee/EditForm';

const Main = () => (
   <Fragment>
    <Switch>
      <Route exact path="/" component={App} />
      <Route exact path="/edit" component={EditForm} />
    </Switch>
  </Fragment>
 )

export default Main;

预期结果:表单使用新输入值更新原始员工 实际结果:表单提交并重定向到主页,但没有任何反应。

【问题讨论】:

  • 嗨 Dylan,检查更新的答案,如果有帮助,请告诉我。

标签: javascript reactjs forms state


【解决方案1】:

我认为问题是这样的,

<Link to='/'>
    <input type="Submit" />
</Link>

你正在用Link 包裹你的input,所以无论何时你点击它都会直接导航到路径/ 而不会执行你的handleSubmit 函数。

你应该只有,

<input type="Submit" />   //Without wrapping with Link

注意:提交表单后,如果要重定向到首页,可以使用react-route-dom包中的Redirect

import { Redirect } from 'react-router-dom'


handleSubmit = (e) => {
    e.preventDefault();
    if (this.props.id) {
      this.props.update(this.state, this.props.id)
    } else {
      this.props.add(this.state)
    }
    this.setState({ firstname: '', lastName: '', phone: '', email: '' })

    return <Redirect to="/" />  //Here you can redirect
}

只需将您的文件替换为以下内容,

App.js

import React, { Component } from 'react';
import Employees from './components/employee/Employees';
import EmployeeForm from './components/employee/EmployeeForm';
import index from './styles/index.scss';


class App extends Component {
    state = {
        employees: [
            { id: 1, firstName: 'Bob', lastName: 'Jones', email: 'bob@email.com', phone: '801-555-5555' },
            { id: 2, firstName: 'John', lastName: 'Doe', email: 'john@email.com', phone: '801-655-5555' },
            { id: 3, firstName: 'Mary', lastName: 'Jane', email: 'mary@email.com', phone: '801-755-5555' }
        ],
        updatedEmployee: '',
    }

    toggleEdit = () => this.setState({ editing: !this.state.editing });

    editEmployee = (employeeData) => {
        const employees = this.state.employees.map(employee => {
            if (employee.id === employeeData.id)
                return employeeData;
            return employee
        });
        this.setState({ employees })
    }

    updateEmployee = (id) => {
        const employees = this.state.employees.filter(employee => employee.id === id);
        this.setState({ updatedEmployee: employees[0] })
    }

    getId = () => {
        // create unique id's
        return Math.floor((1 + Math.random()) * 0x10000)
            .toString(16)
            .substring(1);
    };

    addEmployee = (employeeData) => {
        let newEmployee = { id: this.getId(), ...employeeData }
        this.setState({ employees: [newEmployee, ...this.state.employees] })
    }

    removeEmployee = (id) => {
        const employees = this.state.employees.filter(employee => {
            if (employee.id !== id)
                return employee
        })
        this.setState({ employees: [...employees] })
    }

    render() {
        const { employees } = this.state
        return ( <
            >
            <div class="head">
          Employee Management System
        </div> <
            EmployeeForm add = { this.addEmployee } update = { this.editEmployee } updatedEmployee = { this.state.updatedEmployee }
            /> <
            div class = "emp-header" >
            All Employees <
            /div> <
            Employees employees = { employees } remove = { this.removeEmployee } update = { this.updateEmployee } edit = { this.toggleEdit }
            /> <
            />
        )
    }
}




export default App;

Employee.js

import React from 'react';
import { Link } from 'react-router-dom';

const Employee = ({ id, firstName, lastName, email, phone, remove, edit, update }) => (
  <tr id={id}>
    <td>{id}</td>
    <td>{firstName}</td>
    <td>{lastName}</td>
    <td>{email}</td>
    <td>{phone}</td>
    <td>
      <button class="delete-btn" onClick={() => remove(id)}>
        <strong>Delete</strong>
      </button>
        <button class="edit-btn" onClick={() => update(id)}>
          <strong>Edit</strong>
        </button>
    </td>
  </tr>
)

export default Employee;

Employees.js

import React from 'react';
import { Table } from 'semantic-ui-react';
import Employee from './Employee';

const Employees = ({ employees, remove, edit, update }) => (


  <div class="table">
    <Table celled padded>
      <Table.Header>
        <Table.Row>
          <Table.HeaderCell>Employee ID</Table.HeaderCell>
          <Table.HeaderCell>First Name</Table.HeaderCell>
          <Table.HeaderCell>Last Name</Table.HeaderCell>
          <Table.HeaderCell>Email</Table.HeaderCell>
          <Table.HeaderCell>Phone</Table.HeaderCell>
          <Table.HeaderCell>Options</Table.HeaderCell>
        </Table.Row>
      </Table.Header>
      <Table.Body>
        {
          employees.map(employee => (
            <Employee key={employee.id} {...employee} remove={remove} edit={edit} update={update}/>
          ))
        }
      </Table.Body>
    </Table>
  </div>
)

export default Employees;

EmployeeForm.js

import React, { Component } from 'react';
import { Form, Divider } from 'semantic-ui-react';

class EmployeeForm extends Component {
  state = { 
    id: this.props.updatedEmployee.id, 
    firstName: this.props.updatedEmployee.firstName, 
    lastName: this.props.updatedEmployee.lastName, 
    email: this.props.updatedEmployee.email, 
    phone: this.props.updatedEmployee.phone 
  }

  handleChange = (e) => {
    const { name, value } = e.target
    this.setState({ [name]: value })
  }

  handleSubmit = (e) => {
    e.preventDefault();
    //call add function
    if (this.props.updatedEmployee.id) {
      this.props.update(this.state)
    }else{
      this.props.add(this.state)
    }

    //clear out form 
    this.setState({ id: '', firstName: '', lastName: '', email: '', phone: '' })
  }

  componentDidUpdate(nextProps){
    if(nextProps.updatedEmployee.email !== this.props.updatedEmployee.email){
      this.setState({ 
    id: this.props.updatedEmployee.id, 
    firstName: this.props.updatedEmployee.firstName, 
    lastName: this.props.updatedEmployee.lastName, 
    email: this.props.updatedEmployee.email, 
    phone: this.props.updatedEmployee.phone 
  })
    }
  }

  render() {
    const { firstName, lastName, phone, email } = this.state;
    return (
      <div class="form">
        <form onSubmit={this.handleSubmit}>
          <div class="form-head">
            <Divider horizontal>New Employee</Divider>
          </div>
          <input
            placeholder="First Name"
            required
            name="firstName"
            value={firstName}
            onChange={this.handleChange}
          /><br /><br />
          <input
            placeholder="Last Name"
            required
            name="lastName"
            value={lastName}
            onChange={this.handleChange}
          /><br /><br />
          <input
            placeholder="E-Mail"
            required
            name="email"
            value={email}
            onChange={this.handleChange}
          /><br /><br />
          <input
            placeholder="Phone Number"
            required
            name="phone"
            value={phone}
            onChange={this.handleChange}
          /><br /><br />
          <button class="submit-btn"><strong>Submit</strong></button>
          <br />
        </form>
      </div>
    )
  }
}

export default EmployeeForm;

【讨论】:

  • 我添加路由器链接的原因是我可以在提交表单后重定向到主页。使用您提供的代码时,提交保留在编辑表单页面上。提交后如何重定向到主页(不是 EditForm 页面)?
  • 好的,我从反应路由器添加了重定向,我收到了这个错误。 TypeError:this.props.add 不是函数。 EditForm.handleSubmit src/components/employee/EditForm.js:21
  • 你能显示你在哪里添加了EditForm组件吗?
  • EditForm 组件是&lt;EmployeeForm add={this.addEmployee} update={this.editEmployee} /&gt;
  • 我在代码中添加了 Main.js,它显示了 EditForm 的位置
【解决方案2】:

您的 handleSubmit 函数中存在拼写错误。

不是

this.props.edit(this.state, this.props.id) 

应该是

this.props.update(this.state, this.props.id) 

this.props.edit只执行切换功能,不保存更新。

【讨论】:

  • 谢谢。刚刚修正了错字。结果还是一样。值显示在状态中,但在提交表单时没有任何反应。
  • 你能在Employee组件中看到更新的结果吗?
  • 没有。 Employee 组件只是在主页上显示员工。提交 EditForm 后,我被重定向到主页,但状态仍显示原始员工。
  • 这是因为您使用了 e.preventDefault() 函数。此功能阻止您重定向到主页。
【解决方案3】:

您将this.props.id 作为第二个参数传递给this.props.update,但在App.js 中editEmployee 作为update 传递给表单)只接受一个参数。

尝试更新editEmployee 的签名以采用id 参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-03
    • 2013-05-16
    • 2020-09-25
    • 1970-01-01
    • 1970-01-01
    • 2014-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多