profile
viewpoint

Ask questionsShould have a queue. This is likely a bug in React. Please file an issue

Do you want to request a feature or report a bug?

Report a bug.

What is the current behavior?

I've received this message: "Should have a queue. This is likely a bug in React. Please file an issue."

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:

Tried to reproduce in Sandbox but was unsuccessful: https://codesandbox.io/s/admiring-mayer-2uiiu

Please checkout this repo frozen with this bug above: https://github.com/metamn/react-best-practices/releases/tag/v0.0.1

The bug appeared after adding useMemo in src/components/PlaceholderText/PlaceholderText.js

/**
   * Generates the text rows
   */
  const textRows = useMemo(
    () =>
      [...Array(numberOfRows)].map(i => {
        /**
         * Generates a random uuid
         */
        const id = uuid.v4();

        return {
          id: id,
          text: textRow
        };
      }),
    [numberOfRows, textRow]
  );

What is the expected behavior?

To render the component as usual

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

react": "^16.9.0 Firefox 68.0.2 (64-bit) Ubuntu Ubuntu 18.04.3 LTS

facebook/react

Answer questions Dergash

Hello @metamn! I don't think it's a bug.

What I didn't get is wrongly and will break stuff badly

I believe you did broke rules of hooks by nesting your useMemo calls, and there is a correct console warning about it:

nested-hooks

As pointed out by @threepointone, your

const placeholder = PlaceholderText(props);

assignment didn't actually created a component, you used it as a function that returns an array of { id: string, text: string } objects.

Then you did some mapping and return ArticlesPlaceholder, which is also not a functional component but a function that returns an array of { objectID: string, url: string, title: string } objects.

Then you call it inside another useMemo:

const articlesPlaceholder = useMemo(
    () => ArticlesPlaceholder(placeholder), [placeholder]
);

So, inside useMemo you have a function ArticlesPlaceholder which internally calls a function PlaceholderText which internally has another useMemo, which is directly prohibited:

Don’t call Hooks inside loops, conditions, or nested functions.


About components:

PlaceholderText ... which is a regular function by design. What makes it to be a component?

I believe the function becomes a function component when it's returned by React.createElement :

// either by JSX syntax:
const functionComponent = <PlaceholderText { ...props } />;
// or directly (you JSX transpiler usually do the job of converting JSX syntax
// into React.createElement calls for you:
const functionComponent = React.createElement(PlaceholderText, [props]);

Also function could become a function component when a function itself returns React.createElement call (either JSX.element or an array of JSX elements). That is also not applicable in your case because your PlaceholderText function returns an array of simple objects.

edit: I think the main problem with your approach is that you are treating your PlaceholderText as UI component because you want to memoize some logic, when in fact it is not a component but more like a data that mapped into UI components later.
I've submitted an example merge request that should help to demonstrate how to keep memoization while avoiding nesting useMemo calls. There are of course other ways to handle it.

useful!
source:https://uonfu.com/
answerer
Constantine Dergachev Dergash AT Consulting :electron: Building enterprise software
Github User Rank List