Home > Net >  Map() returning duplicate component
Map() returning duplicate component

Time:11-19

I have a simple function in an application I am building using react, that adds a form text field on a onClick event. I am using map() to add more fields as the user clicks the "add button". The map() is retuning the form text field twice when I need it to just return once when the user clicks the add employees button. How can I edit the code to return just on text field?

import { React, useState } from "react";

import { Button, Form } from "react-bootstrap";
import { Col } from "react-bootstrap";
import { Row } from "react-bootstrap";


const EmployeeName = () => {
  const [input, setInput] = useState([{ empName: "" }]);

  const AddInputField = () => {
    setInput([...input, { empName: "" }]);
  };

  const RemoveInput = (i) => {
    const inputList = [...input];
    inputList.splice(i, 1);
    setInput(inputList);
  }
  
  return (
    <>
      {input.length === 1 ? (
        <Button style={{ display: "inline" }} onClick={AddInputField}>
          click here to add company employees
        </Button>
      ) : (
        <Button style={{ display: "none" }}>
          click here to add company employees
        </Button>
      )}
      {input.length !== 1 &&
        input.map((value, i) => {
          return (
            <Row>
              <Col>
                <Form.Group>
                  <Form.Control
                    key={i}
                    value={value.empName}
                    name="empName"
                    type="text"
                    placeholder="Add Employee Name"
                  />
                </Form.Group>
              </Col>
              <Col>
                <Button
                  onClick={AddInputField}
                >
                  Add
                </Button>
                <Button
                  onClick={() => RemoveInput(i)}
                >
                  Remove
                </Button>
              </Col>
            </Row>
          );
        })}
    </>
  );
};
export default EmployeeName;

CodePudding user response:

I believe I got your code working here in a code sandbox.

Your problem was that you initialized your state with input object that wasn't being displayed until you added a second ("duplicate") input object which then both rendered.

To fix this, all I did was set the initial state to an empty array,

const [input, setInput] = useState([]);

and change the conditional logic to compensate for the different lengths.

 {input.length < 1 ? (
    <Button style={{ display: "inline" }} onClick={AddInputField}>
      click here to add company employees
    </Button>
  ) : (
    <Button style={{ display: "none" }}>
      click here to add company employees
    </Button>
  )}
  {input.length > 0 &&
    input.map((value, i) => {
      return (
        <Row>
          <Col>
            <Form.Group>
              <Form.Control
                key={i}
                value={value.empName}
                name="empName"
                type="text"
                placeholder="Add Employee Name"
              />
            </Form.Group>
          </Col>
          <Col>
            <Button onClick={AddInputField}>Add</Button>
            <Button onClick={() => RemoveInput(i)}>Remove</Button>
          </Col>
        </Row>
      );
    })}

CodePudding user response:

Changing setInput([...input, { empName: "" }]); to setInput(prevState => [...prevState, { empName: "" }]); may help. State updates are asynchronous, so when you're updating based on previous state it's best to pass a function instead of a value.

  • Related