0

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>
  );
}
1
  • The concept is quite straightforward - state value should be initialized with default value when state value is created. And then it is changed by state setter in input change handler. Show us the code of parent component, how the name is initialized in state and how it is changed by onChange handler. Commented Oct 13, 2020 at 8:25

1 Answer 1

1

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);
};
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.