#reactjs #react-hooks
#reactjs #реагирующие крючки
Вопрос:
Мой api возвращает объект следующего типа:
type TApiReturn = {
a: string;
b?: string;
c?: string;
d?: string;
};
Теперь, после получения данных, я хочу передать их часть дочернему компоненту.
type TChildComponent = {
a: string;
c?: string;
};
То, что я думал, сработает:
const [allData, setAllData] = React.useState<TApiReturn>();
const [childData, setChildData = React.useState<TChildComponent>();
useEffect(() => {
const fetchData = async () => {
const result = await api.get('myDataPath'); //this works, not part of it
setData(result.data);
};
fetchData();
}, []);
а затем, чтобы обновить данные дочернего компонента:
useEffect(() => {
let parsedData: TChildComponent;
parsedData.a = data.a;
if (data.c) {
parsedData.c = data.c;
}
setChildData(parsedData);
}, [allData.a]);
Но да, это не может работать, поскольку в начале allData.a
находится undefined
в начале.
Итак, подводя итог: я не уверен, как подойти к этой ситуации. Я понимаю, что у перехватчиков нет функции обратного вызова специально. Но эта ситуация кажется вполне нормальной, поэтому должен быть лучший шаблон проектирования для решения этой проблемы, которого я не вижу.
Ответ №1:
Поскольку состояние должно быть неизменяемым в React, вместо того, чтобы иметь массив зависимостей allData.a
, allData
может работать только зависимость от (и затем вы можете проверить, allData
существует ли, и если да, для allData.a
сравнения childDate.a
).
Но я думаю, что лучшим подходом было бы не разделять одну и ту же структуру данных на несколько переменных с отслеживанием состояния, а просто передавать allData.a
, когда она существует, например:
const [allData, setAllData] = React.useState<TApiReturn>();
// no childData at all
// ...
return (
<Child a={allData?.a} c={allData?.c} />
);
Комментарии:
1. Спасибо. Но когда я попробую предложенный вами подход (передаю данные, если они существуют) Я всегда получаю
Object is possibly 'undefined'. TS2532
.2. Что бы вы хотели, чтобы произошло, когда данные могут еще не существовать и дочерний элемент должен быть визуализирован?
3. Ну, я обернул весь компонент условно, {allData amp;amp; <Дочерний элемент …>} .
4. Если он отображается условно, было бы неплохо просто удалить необязательную цепочку, например:
a={allData.a} c={allData.c}
5. Ну, мой линтер жалуется в любом случае. До сих пор я мог обойти TS2532 только путем инициализации allData с
null
помощью . Я должен разобраться в этом, похоже, подход, который приведет к нежелательным ошибкам. Кроме того, как бы я справился с этим, если бы я не использовал условный рендеринг?