Reputation: 2334
You can see demo here. Try to click "Edit" button and change the value of input field.
In the parent component, it pass an array of objects to its child. Inside the child component, one of objects can be passed into its state, named editedTodo
. But, strangely, the prop is changed when editedTodo
is changed.
This is not what I want. Anyone can help me solve this?
Here is the todo
Component:
import React from "react";
export default class extends React.Component {
state = {
editedTodo: null
};
toggleEditTodo = (todo = null) => {
this.setState({ editedTodo: todo });
};
onChangeTodoText = text => {
this.setState(prevState => ({
editedTodo: Object.assign(prevState.editedTodo, { text })
}));
};
submitTodoForm = e => {
e.preventDefault();
this.props.saveEditedTodo(this.state.editedTodo);
this.setState({
editedTodo: null
});
};
render() {
const { editedTodo } = this.state;
const { todos } = this.props;
return (
<ul>
<li>{JSON.stringify(todos)}</li>
{todos.map(todo => (
<li key={todo.id}>
{todo === editedTodo ? (
<form onSubmit={this.submitTodoForm}>
<input
autoFocus
value={editedTodo.text}
onChange={e => this.onChangeTodoText(e.target.value)}
/>
<button type="submit">Save</button>
<button type="button" onClick={this.toggleEditTodo}>
Cancel
</button>
</form>
) : (
<span>
{todo.text}
<button onClick={() => this.toggleEditTodo(todo)}>Edit</button>
</span>
)}
</li>
))}
</ul>
);
}
}
Upvotes: 1
Views: 65
Reputation: 3830
https://codesandbox.io/s/3q1k4m3vm5
Here is the working version.
The problem was with this.setState({ editedTodo: todo })
. You are assigning the same copy of todo
from the props to the state. So it is referencing the same item. Make sure you are never mutating your props directly, it is an anti-pattern.
Upvotes: 1