React-select: using custom components when isMulti and !closeMenuOnSelect click outside do not close menu

Created on 20 Aug 2020  Â·  11Comments  Â·  Source: JedWatson/react-select

Summary

I'm using react-select version 3.1.0. When I use a custom ValueContainer and closeMenuOnSelect={false}, the menu doesn't close when you click outside the menu.

2020-08-20 11 35 19

Details

When I first open the menu and click away, the menu closes. After I select items and click away, the menu doesn't close. If I then unselect items, the menu still doesn't close when I click away. I checked out issue 2810 from v2, but I am defining the custom component outside of the render and it doesn't solve the problem.

Code

const ValueContainer = ({ children, ...props }) => {
  const { getValue, hasValue, isMulti, selectProps: { placeholder } } = props;
  const numberOfValues = getValue().length;
  if (!hasValue || !isMulti) {
    return (
      <components.ValueContainer {...props}>
        {children}
      </components.ValueContainer>
    );
  }
  return (
    <components.ValueContainer {...props}>
      {`${numberOfValues} ${placeholder}`}
    </components.ValueContainer>
  );
};

const Select = (props) => {
  return (
    <span>
      <ReactSelect
        {...props}
        components={{
          ValueContainer
        }}
        closeMenuOnSelect={true}
        isMulti={true}
      />
    </span>
  );
};

Most helpful comment

I experimented a bit with your sample. Just move your custom components out of the App component. This should fix this issue.

https://codesandbox.io/s/react-codesandboxer-example-forked-m05z9?file=/example.js

Not completely sure why this happens. But if you declare the custom components inside another component, you will get new components on each render, which is most likely a bad idea. :-)

All 11 comments

Looks like it's working as expected now. I must have tweaked something that got it working ¯_(ツ)_/¯

We are running in exactly the same problem. Any chance that you share your latest code?

@chkal I'm really not sure what changed, but I hope this helps! I confirmed that it's still working.

const Select = (props) => {
  const { isMulti, options, placeholder, onMenuClose, isClearable, value, getOptionLabel, getOptionValue, onChange } = props;
  return (
    <span>
      <ReactSelect
        options={options}
        placeholder={placeholder}
        isMulti={isMulti}
        onMenuClose={onMenuClose}
        isClearable={isClearable}
        value={value}
        getOptionValue={getOptionValue}
        getOptionLabel={getOptionLabel}
        onChange={onChange}
        components={{
          ValueContainer,
          Option,
        }}
        closeMenuOnSelect={!isMulti}
        hideSelectedOptions={!isMulti}
        styles={styles}
        {...props}
      />
    </span>
  );
};

Value container:

const ValueContainer = ({ children, ...props }) => {
  const { getValue, hasValue, isMulti, selectProps: { placeholder, inputValue } } = props;
  const numberOfValues = getValue().length;
  if (!hasValue || !isMulti) {
    return (
      <components.ValueContainer {...props}>
        {children}
      </components.ValueContainer>
    );
  }
  return (
    <components.ValueContainer {...props}>
      {
        !inputValue &&
        <components.Placeholder {...props}>{`${numberOfValues} ${placeholder}`}</components.Placeholder>
      }
      {children[1]}
    </components.ValueContainer>
  );
};

@taylorstyers Thanks a lot for sharing your code.

In the meantime we also fixed the issue by adding {children[1]} as the last child of <components.ValueContainer ...>.

Thanks a lot! :beers:

I am facing the same issue, do you know how did you fix it?

@mohuace I posted my updated code above, which is still working. Plus @chkal said how they fixed it. ¯_(ツ)_/¯

Hey, could you guys have a look at this once [https://codesandbox.io/s/react-codesandboxer-example-forked-0kykq?file=/example.js]
Inside handleChange function, I have implemented the logic for the dropdown...having a single select functionality for one of the groups and a multiselect for other groups. I have also added the component Control which is written to provide a tooltip functionality to the dropdown.
In this scenario, I am facing the same issue i.e. when I click outside the dropdown, it doesn't collapse. But when I remove the handleChange function all together, the dropdown seems to be working fine.
Any thoughts on this?
Appreciate your help!

I experimented a bit with your sample. Just move your custom components out of the App component. This should fix this issue.

https://codesandbox.io/s/react-codesandboxer-example-forked-m05z9?file=/example.js

Not completely sure why this happens. But if you declare the custom components inside another component, you will get new components on each render, which is most likely a bad idea. :-)

Ohh, I see. Thanks a lot @chkal , this was really helpful!

That requirement to add {children[1]} was so tricky to find. Is it even documented?

@Dror-Bar I don't think that this is part of the "public API" to be honest.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kopancek picture kopancek  Â·  95Comments

JedWatson picture JedWatson  Â·  35Comments

drobtravels picture drobtravels  Â·  35Comments

obykoo picture obykoo  Â·  34Comments

OsamaShabrez picture OsamaShabrez  Â·  43Comments