10

Using Reac.memo to wrap my functional component, and it can run smoothly, but the eslint always reminded me two errors:

error    Component definition is missing display name  react/display-name

error    'time' is missing in props validation         react/prop-types

Here is my code:

type Data = {
  time: number;
};
const Child: React.FC<Data> = React.memo(({ time }) => {
  console.log('child render...');
  const newTime: string = useMemo(() => {
    return changeTime(time);
  }, [time]);

  return (
    <>
      <p>Time is {newTime}</p>
      {/* <p>Random is: {children}</p> */}
    </>
  );
});

My whole code:

import React, { useState, useMemo } from 'react';

const Father = () => {
  const [time, setTime] = useState(0);
  const [random, setRandom] = useState(0);

  return (
    <>
      <button type="button" onClick={() => setTime(new Date().getTime())}>
        getCurrTime
      </button>
      <button type="button" onClick={() => setRandom(Math.random())}>
        getCurrRandom
      </button>
      <Child time={time} />
    </>
  );
};

function changeTime(time: number): string {
  console.log('changeTime excuted...');
  return new Date(time).toISOString();
}

type Data = {
  time: number;
};
const Child: React.FC<Data> = React.memo(({ time }) => {
  console.log('child render...');
  const newTime: string = useMemo(() => {
    return changeTime(time);
  }, [time]);

  return (
    <>
      <p>Time is {newTime}</p>
      {/* <p>Random is: {children}</p> */}
    </>
  );
});

export default Father;
wentjun
  • 40,384
  • 10
  • 95
  • 107
Liam_1998
  • 1,157
  • 3
  • 12
  • 27

2 Answers2

23

It's because you have eslint config which requries you to add displayName and propTypes

Do something like

const Child: React.FC<Data> = React.memo(({ time }) => {
  console.log('child render...');
  const newTime: string = useMemo(() => {
    return changeTime(time);
  }, [time]);

  return (
    <>
      <p>Time is {newTime}</p>
      {/* <p>Random is: {children}</p> */}
    </>
  );
});

Child.propTypes = {
  time: PropTypes.isRequired
}

Child.displayName = 'Child';
Zohaib Ijaz
  • 21,926
  • 7
  • 38
  • 60
  • Wondering if someone can explain why this only happens when using memo? – Joe Hidakatsu Apr 03 '22 at 22:54
  • 2
    There is a probably a plugin somewhere in your build-pipeline that generates the displayName for react components based on the variable name that the react component is stored in. In the case of React.memo the react component is not stored directly in a variable, but instead is an anonymous function inside the React.memo call. Therefore the displayName cannot be inferred. – sra Jun 03 '22 at 08:02
2

If you are working with React and TypeScript, you can turn off the react/prop-types rule.

This is because TypeScript interfaces/props are good enough to replace React's prop types.

wentjun
  • 40,384
  • 10
  • 95
  • 107
  • Typescript and PropTypes serve different purposes. Typescript validates types at compile-time, whereas PropTypes are checked at runtime. – Someone Special Jul 13 '21 at 04:22
  • @SomeoneSpecial Yep, you are right. My main intention was for the OP to turn off that rule since they do not seem to be using prop-types. I agree my answer was poorly worded. – wentjun Jul 13 '21 at 04:38
  • @SomeoneSpecial the problem with that is it can be extremely difficult to make PropTypes work with TypeScript, as the type definitions between the two are challenging to keep in sync. IMO, PropTypes messages in the browser console get ignored far too much, I would rather have strong compile time TypeScript props than the weak runtime checking that PropTypes offers. – craigmiller160 Jun 27 '23 at 15:23