Search code examples
reactjsreact-select

React-Select focus jumps away when menu is opened


I use a controlled Select element from React-Select inside a form. Whenever I try to open the Select's menu, the focus jumps away to the first input in the page. I can't figure out why.

Here's my component:

import Select from "react-select">

export default function SelectOption({
  name,
  value,
  placeholder,
  options,
  labels,
  disabled_options,
  onChange,
  loading,
  defaultValue,
  filter,
  onBlur,
  inner_ref,
}: Props) {
  const using_options = useMemo(
    () => options.map((value, i) => ({ value, label: labels[i] })),
    [options]
  );

  if (loading) return <LoadingMarker />;

  return (
    <Select
      name={name}
      menuPortalTarget={document.body}
      styles={{ menuPortal: (base) => ({ ...base, zIndex: 9999 }) }}
      options={using_options}
      defaultValue={using_options.find((op) => op.value === defaultValue)}
      isSearchable={filter}
      isClearable={true}
      filterOption={(option, input) => option.label.includes(input)}
      isOptionDisabled={(option) =>
        !!disabled_options && disabled_options.includes(option.value)
      }
      placeholder={placeholder}
      value={using_options.find((op) => op.value == value)}
      onChange={(option) => onChange && onChange(option ? option.value : null)}
      onBlur={onBlur}
      ref={inner_ref}
    />
  );
}

I tried it in several different pages, some with the Select controlled through useForm controller, and some through regular useState. I tried setting value to a constant value. I tried removing every prop but options. It only fixes itself when it's not inside a form.

Can you please help me? I'm at my wits' end


Solution

  • I found the problem. For some ungodly reason, whenever I clicked on the select element it registered as clicking on the form, so it moved the focus to the first input in the form. To fix, add the following to a div wrapping the select, or to the form itself:

       <div onClick={(e) => e.preventDefault()}>
           <Select
            ...
            />
       </div>