Home > Software engineering >  React TS: wait for props before calling function with props as arguments
React TS: wait for props before calling function with props as arguments

Time:11-11

I'm using React through functional components. One of my components has props that are passed by its parent components, like:

const About = () => {
  const { data } = useFetch('About');

  return (
    <div>
      {data && (
        <div>
          <Title title={data.custom_title} />
          <Card
            text={data.body}
          >
            <Skills skills={data.skills} columns={data.n_skills_columns} />
          </Card>
        </div>
      )}
    </div>
  );
};

These props are used in a function to manipulate the prop data before rendering it, such as:

const Skills: FC<SkillsProps> = ({ skills, columns }): JSX.Element => {
  const skillsTable = sliceArray(skills, columns);
  return (
    <div>
      skillsTable.map(...)
    </div>
  );
};

Within the Skills component, the props contain data when I console.log the data with an useEffect hook, nevertheless sliceArray() complains that its arguments are undefined.

What I already tried:

const Skills: FC<SkillsProps> = ({ skills_, columns_ }): JSX.Element => {
  const [skills, setSkills] = useState([]);
  const [columns, setColumns] = useState(1);

  useEffect(() => {
    setSkills(skills_);
    setColumns(columns_);
  }, []);

  const skillsTable = sliceArray(skills, columns);

What am I missing here?

CodePudding user response:

You can add default values to the destructured props. There's no need for a useEffect or useState (unless you're modifying these values somehow in your Skills component).

const Skills: FC<SkillsProps> = ({ skills_ = [], columns_ = 1 }) => {
  const skillsTable = sliceArray(skills, columns);

  return ...;
}

If you don't want to render the Skills component at all before skills_ and columns_ are loaded, then add a loading indicator in the parent component:

const ParentComponent = () => {
  const skills = ...;
  if (!skills) return <>Loading skills...</>;
  return <Skills skills={skills} />;
}
  • Related