react 正在编辑所有数组对象,而不仅仅是一个数组对象

IT技术 reactjs
2021-05-09 09:34:36

目前,用户可以输入名字、姓氏和员工 ID。当它提交时,它会呈现具有第一个、最后一个和员工 ID 的员工迭代。

问题是当您单击编辑时,它会编辑数据,但它会编辑员工迭代中每个对象的所有字段。

我如何修复代码,以便它在该迭代中只编辑该特定对象。

主页组件

........
class Login extends Component {
  constructor(props) {
    super(props);
    this.state = {
      activeTab: '3',
      firstName: '',
      lastName: '',
      employeeID: '',
      employees: [],
      Edit: false,
      updatedFirst: '',
      updatedLast:'',
      updatedEmployeeID: ''
    };
  }
  toggle = (tab) => {
    if(this.state.activeTab !== tab){
      this.setState({
        activeTab: tab
      })
    }
  }
  onSubmit = (e) => {
      e.preventDefault();
      const {firstName, lastName, employeeID} = this.state
      const ourForm ={
          firstName: firstName,
          lastName: lastName,
          employeeID: employeeID,
        // we need an id to so that it can be edited properly
      }
      this.setState({
          employees: [...this.state.employees,ourForm]
      }, () => {
          console.log(this.state.employees)
      })
  }
  onChange = (e) => {
      e.preventDefault()
    // e.preventDefault();
    this.setState({
        [e.target.name]: e.target.value,
    });
  }
  updatedChange = (e) => {
    e.preventDefault()
  // e.preventDefault();
    this.setState({
        [e.target.name]: e.target.value,
    });
  }

  onEdit = (e) => {
      e.preventDefault();
      this.setState({
          Edit: !this.state.Edit
      })
  }

  onReset = (e) => {
      e.preventDefault();
      this.setState({
          firstName: '',
          lastName: '',
          employeeID: ''
      })
  }
  render(){
    return (
            ......
                <MyForm 
                    onSubmit={this.onSubmit} 
                    onChange={this.onChange}
                    onReset={this.onReset}
                    firstName={this.state.firstName}
                    lastName={this.state.lastName}
                    employeeID={this.state.employeeID}
                    />
              </Col> 
            </Row>
          </TabPane>
        </TabContent>
        </Container>

        <List
            employees={this.state.employees}
            Edit={this.state.Edit}
            onEdit ={this.onEdit}
            onChange={this.onChange}
            updatedEmployeeID={this.state.updatedEmployeeID}
            updatedFirst={this.state.updatedFirst}
            updatedLast={this.state.updatedLast}
            />
      </div>
    );
  }
}
export default Login;

表单.js

import React, {Component} from 'react';
import { Col, Form, FormGroup, Label, Input, Button } from 'reactstrap';
const MyForm = (props) => {
    return(
        <Form style={{ margin: '30px 0px'}}>
        <FormGroup row>
          <Label for="firstName"  sm={2} size="sm">First Name:</Label>
          <Col sm={10}>
            <Input type="text" onChange={props.onChange} value={props.firstName} name="firstName" id="exampleEmail" placeholder="Enter First Name"/>
          </Col>
        </FormGroup>
        <FormGroup row>
          <Label for="lastName" sm={2} size="sm">Last Name:</Label>
          <Col sm={10}>
            <Input type="text" onChange={props.onChange} value={props.lastName} name="lastName" id="exampleEmail2" placeholder="Enter Last Name" />
          </Col>
        </FormGroup>
        <FormGroup row>
          <Label for="Employee ID" sm={2} size="sm">Employee ID:</Label>
          <Col sm={5}>
            <Input type="text" onChange={props.onChange} value={props.employeeID} name="employeeID" id="exampleEmail2" placeholder="Enter Employee ID" />
          </Col>
        </FormGroup>
        <FormGroup row>
            <Col sm={12}>
                <div className="float-right">
                    <Button onClick={props.onSubmit} size="lg" style={{ margin: '0px 5px'}} color="secondary">Add</Button> 
                    <Button onClick={props.onReset} size="lg"  style={{ margin: '0px 5px'}}color="warning">Reset</Button>
                </div>
            </Col>
        </FormGroup>
        <hr></hr>
        <FormGroup row>
            <Col sm={4}>
                <Input type="text"  name="search" id="exampleEmail2" placeholder="Search" />   
            </Col>

            <Col sm={8}>
                <Label for="sort" sm={2} size="sm">Sort:</Label>
                <Button onClick={props.onSubmit} size="lg" style={{ margin: '0px 5px'}} color="secondary">First Name</Button>   
                <Button onClick={props.onSubmit} size="lg" style={{ margin: '0px 5px'}} color="secondary">Last Name</Button>  
                <Button onClick={props.onSubmit} size="lg" style={{ margin: '0px 5px'}} color="secondary">ID</Button>  
            </Col>


        </FormGroup>
      </Form>
    )
}
export default MyForm;

列表组件

import React, {Component, Fragment} from 'react';
import { Col, Form, FormGroup, Label, Input, Button } from 'reactstrap';

const List = (props) => {
    return(
        <Fragment>
        {props.employees.map( (item, i) => (
            <div style={{ margin: '40px 0px'}} key={i}>
                <hr style={{ border:'1px dashed #000'}}></hr>
                <div className="float-right">
                    <Button onClick={props.onEdit}  size="lg" style={{ margin: '0px 5px'}} color="secondary">{props.Edit ? 'Save': 'Edit'}</Button> 
                    <Button  size="lg"  style={{ margin: '0px 5px'}}color="secondary">Delete</Button>
                </div>
                <FormGroup row>
                    <Col sm={5}>

                        {props.Edit ? (
                             <Input type="text" onChange={props.onChange} value={ props.updatedFirst ? props.updatedFirst : item.firstName } name="updatedFirst" placeholder="Enter First Name"/>
                        ):(
                           <div>
                          {props.updatedFirst ? props.updatedFirst : item.firstName } 
                           </div>
                        )}

                    </Col>
                </FormGroup>
                <FormGroup row>
                    <Col sm={5}>

                        {props.Edit ? (
                             <Input type="text" onChange={props.onChange} value={ props.updatedEmployeeID ? props.updatedEmployeeID : item.employeeID} name="updatedEmployeeID" placeholder="Enter EmployeeID"/>
                        ):(
                           <div>
                          {props.updatedEmployeeID ? props.updatedEmployeeID : item.employeeID} 
                           </div>
                        )}

                    </Col>
                </FormGroup>
                <FormGroup row>
                    <Col sm={5}>
                    {props.Edit ? (
                             <Input type="text" onChange={props.onChange} value={ props.updatedLast ? props.updatedLast: item.lastName} name="updatedLast" placeholder="Enter Last Name"/>
                        ):(
                           <div>
                          {props.updatedLast ? props.updatedLast : item.lastName} 
                           </div>
                    )}
                    </Col>
                </FormGroup>
            </div>
        ))}
    </Fragment>
    )
}

export default List;
2个回答

以下示例显示了如何传递处理程序并相应地设置状态。

为了更好地衡量,我将逻辑和表示分开,表示组件是使用 React.memo 的纯组件。

//A container should only contain the logic
class EmployeesContainer extends React.Component {
  state = {
    employees: [{ name: '' }, { name: '' }, { name: '' }],
  };
  //define what needs to happen if you click edit on an
  //  employee
  onEdit = index => {
    //edit will be called with the index of the employee
    //  the Employees component owns the list of employees
    //  so it will have to make changes to it
    this.setState({
      employees: this.state.employees.map((employee, i) =>
        i === index ? { ...employee, edit: true } : employee
      ),
    });
  };
  //Same idea as onEdit, index needs to be passed to indicate
  //  what employee needs to be changed
  onChange = (index, e) => {
    this.setState({
      employees: this.state.employees.map((employee, i) =>
        i === index
          ? { ...employee, name: e.target.value }
          : employee
      ),
    });
  };
  render() {
    return (
      <Employees
        employees={this.state.employees}
        onEdit={this.onEdit}
        onChange={this.onChange}
      />
    );
  }
}
//The Employees presentational component, contains the jsx
// you can make it a pure component by using React.memo
const Employees = React.memo(
  ({ employees, onEdit, onChange }) => (
    <div>
      {employees.map((employee, index) => (
        <EmployeeContainer
          key={index}
          index={index}
          employee={employee}
          onEdit={onEdit}
          onChange={onChange}
        />
      ))}
    </div>
  )
);
//Make this a container as well because it does more
//  than only produce jsx
class EmployeeContainer extends React.Component {
  state = {};
  //create onChange and onEdit only when index changes
  //  this will prevent unnecessary renders
  static getDerivedStateFromProps(props, state) {
    const { index, onChange, onEdit } = props;
    if (state.index !== index) {
      return {
        index,
        onChange: e => onChange(index, e),
        onEdit: () => onEdit(index),
      };
    }
    return null;
  }
  render() {
    const { employee } = this.props;
    const { onChange, onEdit } = this.state;
    return (
      <Employee
        employee={employee}
        onChange={onChange}
        onEdit={onEdit}
      />
    );
  }
}
//presentational component, is also pure component
const Employee = React.memo(
  ({ employee, onChange, onEdit }) => (
    <div>
      {employee.edit ? (
        <input
          type="text"
          value={employee.name}
          onChange={onChange}
        />
      ) : (
        <button onClick={onEdit}>edit</button>
      )}
    </div>
  )
);

我认为 onSubmit 没有正确更新员工。你不应该在 setState 中使用 this.state。

setState ReactJS 中的 this.state

试试这个..

this.setState(prevState => ({
      employees: [...prevState.employees, ourForm]
  }, () => {
      console.log(this.state.employees)
  }))