In this example below, I want to reset the input field back to an empty string after clicking submit: https://codesandbox.io/s/todo-app-object-vk99c
Form.js:
class Form extends Component {
state = {
todo: { name: "" }
// inputValue: ""
};
onChange = (e) => {
const newTodo = {
id: Math.random() * 10000,
name: e.target.value,
completed: false
};
this.setState({
todo: newTodo
});
};
onSubmit = async (e) => {
e.preventDefault();
this.props.addTodo(this.state.todo);
console.log(this.state.todo, "this.state.todo 1");
await this.setState({
todo: {}
});
console.log(this.state.todo, "this.state.todo 2");
};
render() {
return (
<form className="Form">
<input
type="text"
className="input"
onChange={this.onChange}
value={this.state.todo.name}
/>
<button className="submit" onClick={this.onSubmit}>
Submit
</button>
{this.state.todo.name}
</form>
);
}
}
export default Form;
App.js:
addTodo = (newTodo) => {
const newState = [...this.state.todos, newTodo];
this.setState({
todos: newState
});
};
My questions are:
I want to update the
namestring to an empty string, and it seems like it works if it's not part of the input field. Why is this happening? Before I click submit: https://i.sstatic.net/0kuEo.jpg , After I click submit: https://i.sstatic.net/TaI13.jpg (Notice how the text next to thesubmitbutton is reseted to an empty string, so why does React update the state in 1 place but not the other?)I got the following warning:
Warning: A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components
at input
at form
at Form (https://vk99c.csb.app/src/Components/Form/Form.js:50:34)
at div
at App (https://vk99c.csb.app/src/App.js:51:34)
Which I think is rather vague. I know the Form (which is a controlled input in React) is the problem, but don't understand what the warning is telling me, and how to fix it.
Update: I believe this code has something to do with it:
onSubmit = async (e) => {
e.preventDefault();
this.props.addTodo(this.state.todo);
console.log(this.state.todo, "this.state.todo 1");
await this.setState({
todo: {
name: {}
}
});
console.log(this.state.todo, "this.state.todo 2");
};
When I changed {} to "", it works, and the warning is gone, but still, I don't understand why it will work at one place but not the other, and what the warning was saying.
EDIT: I got suggested this answer React - changing an uncontrolled input , but it is not my situation, as my initial state wasn't an empty object in Form.js
todo: { name: "" }
this.setState({todo: {}}), since this doesn't have anamekey, usingthis.state.todo.nameas a value doesn't correspond to a state value, as thenamekey does not exist on thetodoobject.submitbutton still being updated (reset to empty string) whereas the string in the input field was not, because they were controlled by the sameonSubmitfunction?onSubmitwill set the state to{todo: {}}, as a resultthis.state.todo.namewill beundefined. React doesn't displayundefinedvalues, so it gets hidden in the output. Since yourvaluefor the input field is now not set to a state value you'll get the error about it being uncontrolled. You can see this by checking for undefined and manually showing a string value:{this.state.todo.name === undefined ? "undefined" : this.state.todo.name}. this will show"undefined"whenthis.state.todo.nameisundefinedundefinedthat it's not being displayed, not because it's an empty string. The value of the input box does not change though, since setting thevaluetoundefinedjust makes the input box "uncontrolled", it doesn't change the value within the textbox/input - more hereundefined, then there is no state driving its value anymore, so it's not being controlled by your applications state (ie: it's uncontrolled). In practice, this could lead to inconsistency between your react state and what's being entered into the input textbox (ie the DOM) - more info in the first paragraph of this article.