How can I reopen a React-Select menu on close?

61 Views Asked by At

i am using react-select, i want to reopen the menu of option on MenuClose using ref, but i cannot do that because the Select element doesn't have the click option in the ref.

here is my component :

import Select from "react-select";
import { useRef } from "react";

export default function App() {
  const ref = useRef();
  const condition = true;

  const options = [
    { value: "chocolate", label: "Chocolate" },
    { value: "strawberry", label: "Strawberry" },
    { value: "vanilla", label: "Vanilla" },
  ];

  const handleMenuClose = () => {
    if (condition) {
      // reopen the menu or keep it opened
    }
  };

  return <Select ref={ref} options={options} onMenuClose={handleMenuClose} />;
}

when i log the ref, here is the list of available options :

{props: Object, context: Object, refs: Object, updater: Object, state: Object, …}
ariaOnChange
: 
ƒ (value, actionMeta)
blockOptionHover
: 
false
blur
: 
ƒ blurInput()
buildCategorizedOptions
: 
ƒ ()
buildFocusableOptions
: 
ƒ ()
clearValue
: 
ƒ ()
commonProps
: 
{clearValue: ƒ, cx: ƒ, getStyles: ƒ, getClassNames: ƒ, getValue: ƒ, …}
context
: 
{}
controlRef
: 
HTMLDivElement
cx
: 
ƒ ()
focus
: 
ƒ focusInput()
focusedOptionRef
: 
null
getCategorizedOptions
: 
ƒ ()
getClassNames
: 
ƒ (key, props)
getComponents
: 
ƒ ()
getControlRef
: 
ƒ (ref)
getElementId
: 
ƒ (element)
getFocusableOptions
: 
ƒ ()
getFocusedOptionRef
: 
ƒ (ref)
getInputRef
: 
ƒ (ref)
getMenuListRef
: 
ƒ (ref)
getOptionLabel
: 
ƒ (data)
getOptionValue
: 
ƒ (data)
getStyles
: 
ƒ (key, props)
getValue
: 
ƒ ()
handleInputChange
: 
ƒ (event)
initialTouchX
: 
0
initialTouchY
: 
0
inputRef
: 
HTMLInputElement
instancePrefix
: 
"react-select-3"
isComposing
: 
false
menuListRef
: 
null
onChange
: 
ƒ (newValue, actionMeta)
onClearIndicatorMouseDown
: 
ƒ (event)
onClearIndicatorTouchEnd
: 
ƒ (event)
onCompositionEnd
: 
ƒ ()
onCompositionStart
: 
ƒ ()
onControlMouseDown
: 
ƒ (event)
onControlTouchEnd
: 
ƒ (event)
onDropdownIndicatorMouseDown
: 
ƒ (event)
onDropdownIndicatorTouchEnd
: 
ƒ (event)
onInputBlur
: 
ƒ (event)
onInputFocus
: 
ƒ (event)
onKeyDown
: 
ƒ (event)
onMenuMouseDown
: 
ƒ (event)
onMenuMouseMove
: 
ƒ (event)
onOptionHover
: 
ƒ (focusedOption)
onScroll
: 
ƒ (event)
onTouchEnd
: 
ƒ (event)
onTouchMove
: 
ƒ (_ref3)
onTouchStart
: 
ƒ (_ref2)
onValueInputFocus
: 
ƒ (e)
openAfterFocus
: 
false
popValue
: 
ƒ ()
props
: 
{options: Array(3), inputValue: '', menuIsOpen: false, onChange: ƒ, onInputChange: ƒ, …}
refs
: 
{}
removeValue
: 
ƒ (removedValue)
scrollToFocusedOptionOnUpdate
: 
false
selectOption
: 
ƒ (newValue)
setValue
: 
ƒ (newValue, action, option)
shouldHideSelectedOptions
: 
ƒ ()
state
: 
{ariaSelection: Object, focusedOption: , focusedValue: null, inputIsHidden: true, isFocused: false, …}
updater
: 
{isMounted: ƒ, enqueueSetState: ƒ, enqueueReplaceState: ƒ, enqueueForceUpdate: ƒ}
userIsDragging
: 
undefined
_reactInternalInstance
: 
{}
_reactInternals
: 
{tag: 1, key: null, stateNode: Object, elementType: ƒ, type: ƒ, …}

i tried using ref but the click option is not available

2

There are 2 best solutions below

0
Kelvin Sherlock On

Maybe you should use the menuIsOpen prop.

https://react-select.com/props

0
0stone0 On

You'll need the controlled component where you can toggle the open/close state manually.


So starting from the example from there documentation:

const Checkbox = (props: JSX.IntrinsicElements['input']) => (
  <input type="checkbox" {...props} />
);

export default () => {
  const ref = useRef<SelectInstance>(null);
  const [menuIsOpen, setMenuIsOpen] = useState<boolean>(false);

  const toggleMenuIsOpen = () => {
    setMenuIsOpen((value) => !value);
    const selectEl = ref.current;
    if (!selectEl) return;
    if (menuIsOpen) selectEl.blur();
    else selectEl.focus();
  };

  return (
    <>
      <Select
        ref={ref}
        defaultValue={colourOptions[0]}
        isClearable
        menuIsOpen={menuIsOpen}
        styles={{ menu: (base) => ({ ...base, position: 'relative' }) }}
        name="color"
        options={colourOptions}
      />
      <Note Tag="label">
        <Checkbox
          checked={menuIsOpen}
          onChange={toggleMenuIsOpen}
          id="cypress-single__clearable-checkbox"
        />
        menuIsOpen
      </Note>
    </>
  );
};

You can use the toggleMenuIsOpen to check your condition and open/close the menu if needed.