Can’t type in controlled input React

  Kiến thức lập trình

I am creating an app that allows users to dynamically create new form fields. When making a new field, I ran into a bug where, when React re-renders my mapped over user input array, the form data was not re-rendered so the forms appeared blank. I realized this was because I did not set the value attributes for my input but after I set them I could no longer type in the input.

The state:

interface FieldObject {
  fieldName: string;
  fieldValue: string;
}

class FieldObject {
  constructor(fieldName: string, fieldValue: string) {
    this.fieldName = fieldName;
    this.fieldValue = fieldValue;
  }
}

const [userInput, setUserInput] = useState([new FieldObject("", "")]);

The map function:

{userInput.map((element, index) => (
          <InputGroup
            key={uuidv4()}
            id={index}
            onChange={(e: React.ChangeEvent) => onChange(e, index)}
            onClick={(e: React.MouseEvent<HTMLButtonElement>) =>
              removeField(e, index)
            }
            inputValue={element.fieldName || ""}
            textAreaValue={element.fieldValue || ""}
          />
        ))}

The input group component:

return (
    <div>
      <TextInput
        id={id.toString()}
        label="Field Name"
        placeholder="Cat Sounds"
        name="fieldName"
        onChange={onChange}
        value={inputValue}
      />
      <TextField
        id={id.toString()}
        label="Field Value"
        placeholder="meow purr"
        onChange={onChange}
        name="fieldValue"
        value={textAreaValue}
      />
      <button onClick={onClick}>Remove</button>
    </div>
  );

The onChange handler:

function onChange(e: React.ChangeEvent, index: number) {
    const target = e.target;
    const newUserInput: Array<FieldObject> = userInput;
    newUserInput[index][target.name] = target.value;
    setUserInput(newUserInput);
  }

The input:

<input
        className="block text-base px-2 pt-2 pb-1 bg-black border-b-2 border-b-slate-700 focus:border-b-white focus:outline-1 focus:outline-offset-8 shadow-lg transition-all"
        id={id}
        type="text"
        placeholder={placeholder}
        value={value}
        onChange={onChange}
        name={name}
      ></input>

I have tried looking around online but most of the similar issues seem to have been fixed with a spelling change. My onChange still console logs but it the console logs show only one character being tracked as changed. Also when the page hot reloads it will render that stored character in the correct input.

Changing value to defaultValue works but I don’t know if that is best practice.

New contributor

Squid is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Theme wordpress giá rẻ Theme wordpress giá rẻ Thiết kế website

LEAVE A COMMENT