从多选反应中选择选项后如何解决重新渲染?

时间:2019-05-22 06:49:42

标签: javascript reactjs multiple-select

当我动态添加下一个输入时,我无法解决为什么重新显示输入的问题。第一步,我从多个选择中单击选择雇员,并使用雇员的ID和姓名动态创建输入。现在我可以为雇员添加分配,但是当我添加下一个雇员时。第一员工的分配值已删除。

1。步骤select employee for project

2。步骤input is created and you can add value of allocation

3。步骤select next employee for project

4。步骤allocation Value of previous employee was cleared

组件ProjectForm(为此问题,我删除了此代码的一些不必要的部分)


export default class ProjectForm extends Component {
  constructor(props) {
    super(props);

    const { project, timurProjects } = this.props;

    this.state = {
      employees:
        project && project.currentEmployees ? project.currentEmployees : [],

      technologies:
        project && project.technologies
          ? project.technologies.map(mapToId)
          : [],
      allTimurProjects: timurProjects,
      allocationValue:
        project && project.currentEmployees ? project.currentEmployees : [],
      projectTimur: null,
    };

    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleUpdateEmployees = this.handleUpdateEmployees.bind(this);
    this.handleUpdateTechnologies = this.handleUpdateTechnologies.bind(this);
  }

  componentDidMount() {
    const { project } = this.props;
    const { allTimurProjects } = this.state;
    this.setState({
      projectTimur: allTimurProjects.find(projectTimur => {
        return project ? projectTimur.code === project.code : false;
      }),
    });
  }

  handleSubmit = values => {
    const { submitProjectForm, project, successText } = this.props;
    const { employees, technologies, projectTimur } = this.state;

    const value = {
      ...values,
      code: projectTimur ? projectTimur.code : null,
      projectManagerId: projectTimur
        ? projectTimur.projectManager.id
        : values.projectManager,
    };

    return submitProjectForm(
      value,
      employees,
      technologies,
      (project && project.id) || null,
    )
      .then(res => {
        displayNotification(successText, 'success');
        const { id } = res.data.project;

        browserHistory.push(`/projects/detail/${id}`);
      })
      .catch(error => {
        throw new SubmissionError(error.response.data.error);
      });
  };

  handleUpdateEmployees(employees) {
    this.setState({
      employees,
    });
  }

  handleUpdateTechnologies(technologies) {
    this.setState({
      technologies,
    });
  }

  handleUpdateAllocation = allocValue => {
    console.log(allocValue, 'ALLOCAVALUE');

    this.setState({
      allocationValue: allocValue,
    });
  };

  render() {
    const {
      projectData,
      project,
      handleSubmit,
      error,
      pristine,
      submitting,
      title,
      submitText,
    } = this.props;

    const {
      employees,
      technologies,
      projectTimur,
      allTimurProjects,
      allocationValue,
    } = this.state;

    const employeesPristine = isEqual(
      employees,
      project && project.currentEmployees ? project.currentEmployees : [],
    );
    const technologiesPristine = isEqual(
      technologies,
      project && project.technologies ? project.technologies.map(mapToId) : [],
    );
    const allocationValuePristine = isEqual(
      allocationValue,
      project && project.currentEmployees ? project.currentEmployees : [],
    );
    const formPristine =
      employeesPristine &&
      technologiesPristine &&
      pristine &&
      allocationValuePristine;

    const defaultPMValue = projectTimur
      ? projectTimur.projectManager.name
      : '--';
    const owners =
      projectTimur && projectTimur.owner.name ? [projectTimur.owner] : [];
    const projectManagers = projectTimur
      ? [projectTimur.projectManager]
      : projectData.projectManagers;

    return (
      <Container>
        <Row>
          <Col>
            <Card className="card-project-add hs-box-shadow mx-auto">
              <CardHeader>
                {project ? (
                  <Row>
                    <Col>
                      <FontAwesome icon={['fab', 'product-hunt']} /> {title}
                    </Col>
                    <Col className="text-right">
                      <Link to={`/projects/detail/${project.id}`}>
                        Show project detail
                      </Link>
                    </Col>
                  </Row>
                ) : (
                  <span>
                    <FontAwesome icon={['fab', 'product-hunt']} /> {title}
                  </span>
                )}
              </CardHeader>
              <CardBody>
                {error && <Alert color="danger">{error}</Alert>}
                <Form
                  onSubmit={handleSubmit(this.handleSubmit)}
                  onKeyPress={blockSubmitOnEnter}
                >
                  <FormRow>
                    </Col>
                    <Col xs="12" lg="5">
                      <Employees
                        title="Project employees"
                        employees={projectData.employees}
                        defaultValue={
                          (project && project.currentEmployees) || []
                        }
                        onUpdate={this.handleUpdateEmployees}
                      />
                      <EmployeeAllocationTable
                        title="Project skills/technologies"
                        employees={employees}
                        project={project}
                        onUpdateAllocation={this.handleUpdateAllocation}
                        defaultValue={
                          (project && project.currentEmployees) || []
                        }
                      />

                    </Col>
                  </FormRow>
                  <FormRow>
                    <Col xs="12" md="4" lg="3">
                      <Button
                        block
                        color="success"
                        type="submit"
                        disabled={formPristine || submitting}
                      >
                        {submitText}
                      </Button>
                    </Col>
                    <Col className="text-md-right mt-3 mt-md-2">
                      <RequiredFieldsNote />
                    </Col>
                  </FormRow>
                </Form>
              </CardBody>
            </Card>
          </Col>
        </Row>
      </Container>
    );
  }
}

组件员工

import PropTypes from 'prop-types';
import Select from 'react-select';
import { FormGroup } from 'reactstrap';

import { getFilteredEmployees } from '../../../util/employees';

class Employees extends Component {
  handleChange(selectedOptions) {
    const { onUpdate } = this.props;
    onUpdate &&
      onUpdate(
        selectedOptions.map(option => ({
          id: option.value,
          label: option.label,
        })),
        console.log(selectedOptions, 'SEL'),
      );
  }

  render() {
    const { title, employees } = this.props;
    let { defaultValue } = this.props;

    defaultValue = defaultValue.map(employee => ({
      value: employee.id,
      label: employee.fullNameInverted || '[unknown name]',
      allocationValue: employee.allocationValue,
    }));
    console.log(defaultValue, 'DV');

    const filteredEmployees = getFilteredEmployees(employees);

    const options = filteredEmployees.map(employee => ({
      value: employee.id,
      label: employee.fullNameInverted,
      allocationValue: employee.allocationValue,
    }));

    return (
      <FormGroup>
        <label>{title}</label>
        <Select
          defaultValue={defaultValue}
          isMulti
          options={options}
          onChange={this.handleChange.bind(this)}
        />
      </FormGroup>
    );
  }
}

Employees.propTypes = {
  title: PropTypes.any,
  employees: PropTypes.array.isRequired,
  defaultValue: PropTypes.array,
  onUpdate: PropTypes.func,
};

export default Employees;

Component.EmployeeAllocationTable

import { Table, Input } from 'reactstrap';

export default class EmployeeAllocationTable extends Component {
  constructor(props) {
    super(props);
    let { defaultValue } = this.props;

    defaultValue = defaultValue.map(employee => ({
      value: employee.id,
      label: employee.fullNameInverted || '[unknown name]',
      allocationValue: employee.allocationValue,
    }));

    this.state = {
      value: defaultValue,
      key: defaultValue,
      allocationValue: '',
    };
    console.log('State', this.state);
  }

  handleChangeInput = e => {
    const { employees } = this.props;
    const { name, value } = e.target;
    console.log(name, 'Name', value, 'Value');
    const employeesList =
      employees &&
      employees.find(
        employeeLabel => employeeLabel.id.toString() === e.target.name,
      );
    employeesList.allocationValue = e.target.value;
    e.preventDefault();
    this.props.onUpdateAllocation(employeesList.allocationValue);

    this.setState({
      [name]: value,
    });
  };

  render() {
    const { employees } = this.props;

    const newEmployeesTable =
      employees &&
      employees.map(employee => {
        const employeesList =
          employees &&
          employees.find(employeeLabel => employeeLabel.id === employee.id);

        return (
          <tr key={employee.id}>
            <td>{employeesList.fullName || employeesList.label}</td>
            <td>{employeesList.allocationValue} %</td>

            <td>
              <Input
                name={employee.id.toString()}
                value={employee.allocationValue}
                onChange={this.handleChangeInput}
                placeholder="Allocation on the project (%) "
                maxLength="3"
              />
            </td>
          </tr>
        );
      });

    return (
      <div>
        <Table>
          <thead>
            <tr>
              <th>Name</th>
              <th>Allocation on the project</th>
            </tr>
          </thead>
          <tbody>{newEmployeesTable}</tbody>
        </Table>
      </div>
    );
  }
}

1 个答案:

答案 0 :(得分:0)

这是什么?

const employeesList =
      employees &&
      employees.find(employeeLabel => employeeLabel.id === employee.id);

upd:如果您不想重新渲染表,则不应在选择更改时调用onUpdate道具(handleUpdateEmployees) 您还可以对对象

做一些事情
onUpdate(
    selectedOptions.map(option => ({
      id: option.value,
      label: option.label,
      //add here allocation and input value
    })),