John Elijah
John Elijah

Reputation: 29

react-hook-form react-select in functional component gives warning

I am using react-select 5.2.2, reack-hook-form 7.19.5 and react 17.0.2

Everything is working fine in my component except when I select value in the react-select drop down it throws following warning in the console:

A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component.

here is my code for the component

const [selectedOption, setSelectedOption] = useState(undefined);
const { data: userAreas } = useQuery(GET_AREAS);

const areasList = userAreas && userAreas.getAreasList.map((obj) => {
    const rObj = {};
    rObj.areaValue = obj;
    rObj.label = obj;
    return rObj;
  });

<Label>Area</Label>
          <Controller
            name="area"
            control={control}
            rules={{ required: 'Area is required' }}
            render={({ field }) => (
              <ReactSelect
                isClearable
                {...field}
                placeholder="Select Your Area"
                value={selectedOption}
                onChange={setSelectedOption}
                options={areasList}
              />
            )}
          />

{areasList} is coming from graphql useQuery so initially it is undefined until it receives data in subsequent renders

I have further revised the code to exclude undefined but the warning still occurs. Here is the revised code

const { data: userAreas } = useQuery(GET_AREAS);

const areasList = userAreas?.getAreasList.map((obj) => {
    const rObj = {};
    rObj.areaValue = obj;
    rObj.label = obj;
    return rObj;
  }) || [];

<Label>Area</Label>
          <Controller
            name="area"
            control={control}
            rules={{ required: 'Area is required' }}
            render={({ field }) => (
              <ReactSelect
                isClearable
                {...field}
                placeholder="Select Your Area"
                options={areasList}
              />
            )}
          />

Upvotes: 2

Views: 4762

Answers (2)

John Elijah
John Elijah

Reputation: 29

Replacing

<Controller
    name="area"
    control={control}
    rules={{ required: 'Area is required' }}
    render={({ field }) => (
        <ReactSelect
           isClearable
           {...field}
           placeholder="Select Your Area"
           options={areasList}
        />
    )}
/>

with

<Controller
            name="area"
            control={control}
            rules={{ required: 'Area is required' }}
            render={({ field }) => (
              <ReactSelect
                isClearable
                value={field.value}
                onChange={field.onChange}
                ref={field.ref}
                placeholder="Select Your Area"
                options={areasList}
              />
            )}
          />

fixed my problem.

Upvotes: 1

Ozan Mudul
Ozan Mudul

Reputation: 1010

you are changing uncontrollable component to controllable

check this documentation

the value is undefined at the first render so it is uncontrollable then the value is changed and your component became controllable

the value attribute should be like this

selectedOption ?? <empty data here>

Upvotes: 0

Related Questions