Search code examples
javascriptreactjsreact-hookshtml-inputuse-effect

useEffect throws an error when used to set input value


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.


Solution

  • 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.