Reputation: 187
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
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