#reactjs #typescript #ionic-framework #react-hooks
#reactjs #typescript #ионный фреймворк #реагирующие хуки
Вопрос:
В моем функциональном компоненте / странице у меня есть const / function, которому я передаю сообщения об ошибках, который затем обновляет пару записей useState и регистрирует ошибку на консоли. Это выглядит так:
const catchError = (e:any, message:string) => {
//throw new Error(e)
setMessage(message);
setLoading(false);
console.error(e);
};
Я хотел бы переместить этот код в хук (?) / вспомогательный файл, который позволит мне импортировать его в любой другой компонент. Это означало бы, что я могу использовать один централизованный фрагмент кода, а не писать один и тот же код в нескольких местах и избегать связанных с этим проблем.
Итак, я создал новый catchError.tsx
файл со следующим содержимым:
import { useState } from 'react';
const [ message, setMessage ] = useState("idle");
const [ loading, setLoading ] = useState(false);
export const catchError = (e:any, message:string) => {
//throw new Error(e)
setMessage(message);
setLoading(false);
console.error(e);
};
Однако, когда я визуализирую это, я получаю следующую ошибку компиляции:
Не удалось скомпилировать
Строка src / hooks / catchError.tsx 3:33: Реагирующий хук «useState» не может быть вызван на верхнем уровне. Реагирующие хукеры должны вызываться в компоненте функции React или пользовательской функции React-hooks / rules-of-hooks Строка 4:33: Реагирующий хук «useState» не может быть вызван на верхнем уровне. Реагирующие хукеры должны вызываться в компоненте функции React или пользовательской функции React-Hook react-hooks / rules-of-hooks
Найдите ключевые слова, чтобы узнать больше о каждой ошибке.
Для меня это новая территория.
(PS: я новичок в React / TypeScript и буду приветствовать любые исправления в моей терминологии).
Комментарии:
1. имя файла
catchError.tsx
и имя функции должны иметь префиксuse
like thisuseCatchError
, чтобы react распознал его как пользовательский хук. Кроме того, вы должны переместить свои пользовательские состояния внутри функции
Ответ №1:
Если вы хотите повторно использовать логику хуков (например, useState), вы можете написать свои собственные пользовательские хуки.
Я считаю, что что-то вроде so может сработать, хотя я не совсем уверен, как это будет использоваться без дополнительного контекста.
import { useState } from 'react';
function useCatchError() {
const [ message, setMessage ] = useState("idle");
const [ loading, setLoading ] = useState(false);
const catchError = (e:any, message:string) => {
//throw new Error(e)
setMessage(message);
setLoading(false);
console.error(e);
};
return { catchError, message, loading };
}
И использоваться как
export function Foo() {
const {catchError, message, loading} = useCatchError();
try {
bar();
} catch (e) {
catchError(e, e.message);
}
return (
<div>
{message ? `Error: ${message}` : loading ? "Loading" : "Foo"}
</div>
);
}
Подробнее о пользовательских хуках в документах React: https://reactjs.org/docs/hooks-custom.html
Комментарии:
1. Спасибо. Я не хочу ничего возвращать, мне просто нужно передать 2 значения (e и message). Затем используйте
catchError
с любой другой страницы / компонента, импортировав его. Если я импортирую useCatchError в соответствии с вашим кодом и импортирую приimport { catchError } from '../hooks/useCatchError';
получении ошибкиModule '"../hooks/useCatchError"' has no exported member 'catchError'.
, какие-либо предложения?2. P.s. Мой код catchError буквально соответствует тому, что я опубликовал в своем вопросе. Мне просто нужно иметь возможность повторно использовать этот код на нескольких компонентах / страницах без ручного добавления этого кода полностью на каждую страницу. Спасибо.
3. Если вы не хотите возвращать сообщение и значение загрузки, которое вы можете заменить,
return { catchError, message, loading };
return catchError
и тогда вы сможете получить эту функциюconst catchError = useCatchError();
. Однако вам нужно вызывать хук в вашем методе рендеринга для каждого компонента, обойти это невозможно.