Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extended AutocompleteInput with useChoicesContext and optionText clears itself and flickers #8545

Closed
harastaivan opened this issue Jan 4, 2023 · 3 comments

Comments

@harastaivan
Copy link

harastaivan commented Jan 4, 2023

What you were expecting:

Input should behave like normal AutocompleteInput. Same as without using useChoicesContext, options don't flicker, input doesn't clear itself after network call.

What happened instead:
After network call is made to ReferenceInput's reference, the input clears, the dropdown show previous options and then flickers the filtered options.

Steps to reproduce:
Go to any PostEdit, first input is Test users, type in something, then the flickering and input text clear happen.

Related code:
https://stackblitz.com/edit/github-jnpt6d?file=src%2Fposts%2FUserReferenceInput.tsx,src%2Fposts%2FPostEdit.tsx,src%2Fposts%2FUserAutocompleteInput.tsx

Go to any src/posts/PostEdit.tsx, first input is

<ArrayInput source="test_users" fullWidth>
  <SimpleFormIterator inline>
    <UserReferenceInput />
  </SimpleFormIterator>
</ArrayInput>

inside UserReferenceInput there is UserAutocompleteInput which reproduces the issue.

The bug is reproducible when UserAutocompleteInput uses both:

  • useChoicesContext to somehow read the choices
  • optionText, inputText and matchSuggestion functionality.

I tried passing all the props or forwarding the ref which didn't help.

Environment:

  • React-admin version: 4.6.2
  • React version: 17.0.2
  • Browser: Chrome 108
@slax57
Copy link
Contributor

slax57 commented Jan 4, 2023

Thanks for this report.

Playing a bit with your stackblitz, I was able to narrow it down to the fact that the React Element passed to optionText needs to be memoized (or a constant).

I.e. the following makes the flicker disappear:

const memoizedOptionUser = <OptionUser />;

export const UserAutocompleteInput = () => {
  // When I comment out useChoicesContext it behaves correctly
  const choices = useChoicesContext();
  useEffect(() => {
    console.log(choices.allChoices);
  }, [choices]);

  return (
    <AutocompleteInput
      label="Select flickering user"
      optionText={memoizedOptionUser}
      inputText={inputText}
      matchSuggestion={matchSuggestion}
    />
  );
};

This can be your workaround for now.

It would be better if we could memoize the Element on our end though, so I'll mark this as a bug and we'll take some time to dig into it.

Btw this could maybe help: https://epicreact.dev/the-latest-ref-pattern-in-react/

One more thing, please pay attention to this section of the docs:

Caution: <SimpleFormIterator> clones its children several times, as it needs to override their actual source for each record. If you use a custom Input element, make sure they accept a custom source prop.

I noticed you didn't do it in your stackblitz.

@slax57 slax57 added the bug label Jan 4, 2023
@djhi
Copy link
Contributor

djhi commented Jun 23, 2023

Can you share a bit more about what you're trying to achieve? I fail to understand why you would call useChoicesContext without using any of the values it returns

@fzaninotto
Copy link
Member

No news for some time, closing.

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

No branches or pull requests

4 participants