Fan Cheung
Fan Cheung

Reputation: 11345

What's the difference between functional component and create component using useMemo() in React

are these two method of component construction the same?

const myComp=(props)=><h1>props.text</h1>

vs

const myComp=useMemo((props)=><h1>props.text</h1>)

they both renders on props change

Upvotes: 2

Views: 73

Answers (2)

Giraphi
Giraphi

Reputation: 1651

Short answer

  • Using useMemo without dependency array will do nothing.
  • Generally speaking, don't use useMemo to define components.
  • To make sure you are using useMemo correctly, set up your linter like here

Long answer:

A couple of things first:

Note that useMemo can only be used within another component or hook (see here) so I'll assume that for the rest of the answer.

I'd say your usage of useMemo is incorrect. If you want to define a component with it (however you probably shouldn't) it could be like this:

  const MyComp = useMemo(
    () => (props) => (
      <h1>
        {props.text}
      </h1>
    ),[]
  );

This defines a functional component and redefines it whenever the dependencies change. (Here the dependencies are [], so it will be defined only once). Note that using useMemo without a dependency array will result in a linting error (react-hooks/exhaustive-deps) if you set up your linting correctly as suggested here.

If you insist on leaving out the dependency array, useMemo will do nothing.

To play around a little bit with different scenarios, take a look at this codesandbox

  const MyCompA = (props) => (
    <h1>
      {props.text}
      {counter}
    </h1>
  );

  // Equivalent to MyCompA. Gives linting error
  const MyCompB = useMemo(() => (props) => (
    <h1>
      {props.text}
      {counter}
    </h1>
  ));

  // Will only be defined once and not notice changes to counter. Gives linting error
  const MyCompC = useMemo(
    () => (props) => (
      <h1>
        {props.text}
        {counter}
      </h1>
    ),
    []
  );

  // Will notice changes to counter. But generally, this  is not
  // much better than MyCompA
  const MyCompD = useMemo(
    () => (props) => (
      <h1>
        {props.text}
        {counter}
      </h1>
    ),
    [counter]
  );

MyCompA and MyCompB do the same thing, because MyCompB uses useMemo without dependencies. MyCompC uses that state counter but doesn't recognize changes, because it's not in the dependency array. MyCompC recognizes that changes, but overall is not much better than MyCompA.

Note the whole example is for "playing-around purpose" only so we can inspect how useMemo behaves. Generally speaking, defining components with useMemo is probably not the way to go. For that example, better use a regular component that takes both text and counter as props.

Upvotes: 2

Estus Flask
Estus Flask

Reputation: 222493

useMemo doesn't affect function calls and the way a component reacts to prop changes in this case. This could be achieved with useCallback but it's not recommended; this is what memo component is for.

Considering that both are defined inside component function, the one without useMemo will be a new component on each render and so will be remounted, while the one with useMemo will behave as expected.

Since the component doesn't rely on the scope in which it's defined (it's not a good practice), it shouldn't be defined inside another component and therefore won't benefit from the use of useMemo.

Upvotes: 1

Related Questions