How to implement a Select component?

Hi there, I’ve been trying to implement a select component in my page. The designing worked and I can also preview the page with the select component working as expected (one click shows and one click hides again). However, if I then sync the project with my local code using codegen, it starts to behave weird. Multiple clicks are required to open the dropdown and it seems to behave kind of random. There are also no errors logged which may hint to the issue. Do you maybe know, what’s going on here?

Interestingly, if I set onOpenChange to just console.log, it sets it to true as soon as you click as expected but then immediately sets it back to false. However, I haven’t touched the parent component nor the generated select component (besides injecting the onOpenChange once for checking what happens)

That’s interesting, do you have a small reproducible GitHub repo exhibiting the issue? We can take a look

sure, I’ve created one together with a list of steps I did: https://github.com/lukasbischof/plasmic-custom-select

Thanks!

@yang Have you been able to look into it yet?

Yes, your example was super helpful in letting us reproduce it, thank you - still fixing

Ok, thank you for the update and your effort!

Hi! As it turns out, the library that we use under the hood for our Select component is react-aria, and it currently has some issues when used within React.StrictMode. You can work around this for now by removing the React.StrictMode wrapper from your index.js (create-react-app just recently started using the wrapper by default)

@yang Have you been able to look into it yet?

Yes, your example was super helpful in letting us reproduce it, thank you - still fixing

Ok, thank you for the update and your effort!

Hi! As it turns out, the library that we use under the hood for our Select component is react-aria, and it currently has some issues when used within React.StrictMode. You can work around this for now by removing the React.StrictMode wrapper from your index.js (create-react-app just recently started using the wrapper by default)

Ok, thank you very much for your investigation and your effort. Removing the strict mode indeed solves the issue. However, we don’t really want to remove it, since we’re in an early development stage… Hence, I came up with another dirty fix (quite ugly but at least it contains the issue only to the select component and does not affect other development). I guess we’ll then just need to wait for react-aria to fix the issue.
Here’d be my fix, if anybody else is interested or has the same issue:

function Select_(props: SelectProps, ref: SelectRef) {
  const { onChange } = props;
  const [isOpen, setIsOpen] = React.useState(props.isOpen || false);
  const [value, setValue] = React.useState(props.value);

  const debouncedOpen = React.useMemo(
    () => debounce((isOpen: boolean) => setIsOpen(!isOpen), 100, { leading: true, trailing: false }),
    []
  );

  React.useEffect(() => onChange && onChange(value || null), [value, onChange]);

  const { plasmicProps } = PlasmicSelect.useBehavior(
    { ...props, isOpen: isOpen, value: value, onOpenChange: () => debouncedOpen(isOpen), onChange: setValue },
    ref
  );

  return <PlasmicSelect {...plasmicProps} />;
}

Probably the delay of 100ms could even be reduced further

Note too that strict mode is only in effect in development mode, so things still work when you build for production. But yeah annoying that you can’t open Select in development mode :persevere: