Skip to content

using custom components when isMulti and !closeMenuOnSelect click outside do not close menu #4170

Closed

Description

@taylorgannon

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>
  );
};

Activity

  1. taylorgannon commented on Aug 20, 2020

    @taylorgannon
    Author

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

  2. chkal commented on Aug 28, 2020

    @chkal

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

  3. taylorgannon commented on Aug 28, 2020

    @taylorgannon
    Author

    @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>
      );
    };
    
  4. chkal commented on Aug 28, 2020

    @chkal

    @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! 🍻

  5. mohuace commented on Sep 4, 2020

    @mohuace

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

  6. taylorgannon commented on Sep 4, 2020

    @taylorgannon
    Author

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

  7. mohuace commented on Sep 7, 2020

    @mohuace

    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!

  8. chkal commented on Sep 8, 2020

    @chkal

    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. :-)

  9. mohuace commented on Sep 8, 2020

    @mohuace

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

  10. Dror-Bar commented on Nov 29, 2020

    @Dror-Bar

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

  11. chkal commented on Nov 29, 2020

    @chkal

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

  12. Falzaro commented on Jan 14, 2021

    @Falzaro

    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. :-)

    You can't create a component within a functional component.

    This 2-minute article explains why:
    https://dev.to/borasvm/react-create-component-inside-a-component-456b#:~:text=So%20the%20take%20away%20%2D%20NEVER,COMPONENT%20INSIDE%20ANOTHER%20FUNCTION%20COMPONENT.&text=Functions%20are%20not%20part%20of,called%20when%20component%20re%2Drender.

  13. ebonow commented on Jan 14, 2021

    @ebonow
    Collaborator

    This has come up in several times and is an easy mistake to make, and thought it might be worth mentioning that the following section was added to the documentation as part of the v3.2 release.

    https://react-select.com/components#defining-components

  14. faizantroon commented on Aug 4, 2023

    @faizantroon

    Today i have come across with this issue and i resolved it by moving my custom components outside of React functional component, Basically you can't define functional component within another functional component because it cause re renders and it will not close the dropdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions