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} />;
}