I'm trying to make an input component that will be controlled by react and that will update it's value whenever a props is changed.
This is how I'm doing it:
import React from 'react';
function Component(props) {
const [url, setUrl] = React.useState(props.value);
React.useEffect(() => {
setUrl(props.value);
}, [props.value]);
function handleChange(event) {
setUrl(event.target.value)
}
return (
<div>
<input
type="text"
onChange={handleChange}
value={url}
/>
</div>
);
}
Although the logic works I still get an error saying that my component is switching from controlled to uncontrolled, but I don't see why this would be the case.
I don't understand the purpose of useEffect
here. If the parent component's state changes, then the props of the child component will update automatically as it will trigger a rerender. Just remove your useEffect
code and it should work fine.
Furthermore, I believe this will trigger an infinite loop because each time url
is updated, it would trigger the useEffect
hook, which would update the url
, which would trigger useEffect
etc.
It would also be a good idea to set a default value on props.value
:
const [url, setUrl] = React.useState(props.value || '');
By the way, I would use useCallback
for your handleChange
method.
const handleChange = React.useCallback((event) => setUrl(event.target.value), []);
This will memoize the function for better performance.