Reputation: 297
I'm learning React and I created a really simple "shopping list app". Everything is working now but I'm getting this error: "Warning: A component is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component".
Here it is my code:
function InputArea(props) {
const [inputText, setInputText] = useState({
inputText: {text: ""}
});
function handleChange(event){
setInputText(event.target.value);
}
function handleClick(event) {
props.onSubmit(inputText);
setInputText({text: ""});
event.preventDefault();
}
return(
<div className="input-group w-50">
<input
type="text"
className="form-control"
onChange={handleChange}
ariadescribedby="button-addon"
value={inputText.text}
placeholder="Insert Item">
</input>
<div className="input-group-append">
<Button
id="button-addon"
color="dark"
style={{marginBottom: "2rem"}}
onClick={handleClick}>Add Item
</Button>
</div>
</div>
)
}
The problem appears when I want to reset my input, in order to see the placeholder instead of the name of the last item added.
Upvotes: 1
Views: 886
Reputation: 281686
The issue is in how you are updating state, how you use the state and how you initialise it.
With hooks unlike setState
in classes, the values of state updater are not merged but replaced and when you run
setInputText({text: ""});
your inputText is replaced from its previous structure of
{
inputText: {text: ""}
}
Causing you the error
Since you are using inputText.text
to set value of input filed you must initialise the state also in that manner
const [inputText, setInputText] = useState({
text: ""
}); // initialise as an object
function handleChange(event){
setInputText({ text: event.target.value }); // update the state object with text field
}
function handleClick(event) {
props.onSubmit(inputText);
setInputText({text: ""});
event.preventDefault();
}
return(
<div className="input-group w-50">
<input
type="text"
className="form-control"
onChange={handleChange}
ariadescribedby="button-addon"
value={inputText.text}
placeholder="Insert Item">
</input>
<div className="input-group-append">
<Button
id="button-addon"
color="dark"
style={{marginBottom: "2rem"}}
onClick={handleClick}>Add Item
</Button>
</div>
</div>
)
Upvotes: 1