React TS: дождитесь реквизитов, прежде чем вызывать функцию с реквизитами в качестве аргументов

#reactjs #typescript

Вопрос:

Я использую React через функциональные компоненты. У одного из моих компонентов есть реквизиты, которые передаются его родительскими компонентами, например:

 const About = () =gt; {  const { data } = useFetch('About');   return (  lt;divgt;  {data amp;amp; (  lt;divgt;  lt;Title title={data.custom_title} /gt;  lt;Card  text={data.body}  gt;  lt;Skills skills={data.skills} columns={data.n_skills_columns} /gt;  lt;/Cardgt;  lt;/divgt;  )}  lt;/divgt;  ); };  

Эти реквизиты используются в функции для управления данными реквизитов перед их отображением, например:

 const Skills: FClt;SkillsPropsgt; = ({ skills, columns }): JSX.Element =gt; {  const skillsTable = sliceArray(skills, columns);  return (  lt;divgt;  skillsTable.map(...)  lt;/divgt;  ); };  

Внутри Skills компонента реквизиты содержат данные, когда я выполняю консоль.регистрируйте данные с помощью крючка useEffect, тем не менее sliceArray() жалуется, что его аргументы таковы undefined .

То, что я уже пробовал:

 const Skills: FClt;SkillsPropsgt; = ({ skills_, columns_ }): JSX.Element =gt; {  const [skills, setSkills] = useState([]);  const [columns, setColumns] = useState(1);   useEffect(() =gt; {  setSkills(skills_);  setColumns(columns_);  }, []);   const skillsTable = sliceArray(skills, columns);  

Что я здесь упускаю?

Комментарии:

1. Откуда берутся реквизит skills и columns реквизит? Как вы передаете их Skills компоненту?

2. Я добавил родительский компонент в вопрос, чтобы вы могли видеть, как передаются реквизиты

3. Это useFetch пользовательский крючок или из библиотеки, как react-query ?

4. Это пользовательский крючок, который работает в других компонентах

5. Вы убедились, что data это всегда либо ложь (например undefined ), либо объект с ключами skills и n_skills_columns ?

Ответ №1:

Вы можете добавить значения по умолчанию в деструктурированные реквизиты. Нет необходимости в useEffect или useState (если только вы каким-то образом не изменяете эти значения в своем Skills компоненте).

 const Skills: FClt;SkillsPropsgt; = ({ skills = [], columns = 1 }) =gt; {  const skillsTable = sliceArray(skills, columns);   return ...; }  

Если вы вообще не хотите визуализировать Skills компонент до skills_ и columns_ после загрузки, добавьте индикатор загрузки в родительский компонент:

 const ParentComponent = () =gt; {  const skills = ...;  if (!skills) return lt;gt;Loading skills...lt;/gt;;  return lt;Skills skills={skills} /gt;; }  

Комментарии:

1. Это именно то, что я искал.