jetski
jetski

Reputation: 187

How to edit input with default value in ReactJS

So, are there any other ways, rather than changing value to defaultValue to change the input value manually? (When using defaultValue My program doesn't work properly)

ChildComponent = React.memo(
  ({ name, index, onChange, onDelete
  }) => {
    return (
      <div>
        <input value={name} onChange={onChange(index, name)} />
        <button onClick = {() => onDelete(index)}>delete</button>
      </div>
    );
  }
);
 function App() {
  const [names, setNames] = React.useState(["First", "Second"]);
  const newName = React.useRef();

  const onNameChange = (index: number, newName: string) => (event: {
    target: { value: string };
  }) => {
    names[index] = event.target.value;
    setNames(names);
  };
  function onNameDelete(index: number) {
    const nameArr = [...names];
    nameArr.splice(index, 1);
    setNames(nameArr);
  }
  return (
    <div>
      {names.map((name, index) => (
        <ChildComponent
          key={index}
          name={name}
          index={index}
          onChange={onNameChange}
          onDelete={onNameDelete}
        />
      ))}
    </div>
  );
}

Upvotes: 0

Views: 1561

Answers (1)

lavor
lavor

Reputation: 1877

The issue is in your onChange input handler in your ChildComponent. You are not using passed value by user to input at all. You need to write it similarly to your onDelete handler (with use the new value, in my snippet stored in event.target.value):

ChildComponent = React.memo(
  ({ name, index, onChange, onDelete
  }) => {
    return (
      <div>
        <input value={name} onChange={(event) => onChange(index, event.target.value)} />
        <button onClick = {() => onDelete(index)}>delete</button>
      </div>
    );
  }
);

Look also on the definition of the input change handler in Html documentation.

EDIT: Another issue is your handler in your parent controller:

 const onNameChange = (index: number, newName: string) => (event: {
    target: { value: string };
  }) => {
    names[index] = event.target.value; //this is BAD, do not change your state value directly, moreover, the event is undefined here
    setNames(names);
  };

You need to update item in the array immutably (source Updating an Item in an Array):

const onNameChange = (index: number, newName: string) => (event: {
  target: { value: string };
}) => {
  const newNames = names.map((item, itemIndex) => {
    if (itemIndex !== index) {
      // This isn't the item we care about - keep it as-is
      return item
    }

    // Otherwise, this is the one we want - return an updated value
    return newName;
  });
  setNames(newNames);
};

Upvotes: 1

Related Questions