Как сказано в заголовке, как правильно использовать пользовательский хук для обработки события onClick?
Это приложение codesandbox будет отображать новую цитату на экране, когда пользователь щелкает поиск button.
function App() {
const [{ data, isLoading, isError }, doFetch] = useDataApi(
"https://api.quotable.io/random"
);
return (
<Fragment>
<button disabled={isLoading} onClick={doFetch}>
Search
</button>
{isError && <div>Something went wrong ...</div>}
{isLoading ? <div>Loading ...</div> : <div>{data.content}</div>}
</Fragment>
);
}
Я создал пользовательский хук с именем useDataApi()
, который будет получать новую цитату из API. Чтобы обновить цитату, когда пользователь нажимает кнопку внутри useDataApi()
, я создал handleClick()
, который изменит значение щелчка для запуска повторного рендеринга. И эта handleClick()
функция вернется обратно к App()
const useDataApi = initialUrl => {
const [data, setData] = useState("");
const [click, setClick] = useState(true);
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);
const handleClick = () => {
setClick(!click);
};
useEffect(() => {
const fetchData = async () => {
setIsError(false);
setIsLoading(true);
try {
const result = await axios(initialUrl);
setData(result.data);
} catch (error) {
setIsError(true);
}
setIsLoading(false);
};
fetchData();
}, [initialUrl, click]);
return [{ data, isLoading, isError }, handleClick];
};
Это работает, однако я не думаю, что это правильное решение.
Я также пытался переместить fetchData()
из useEffect
и вернуть fetchData()
, и это тоже работает. Но согласно React Do c говорится, что рекомендуется перемещать функции внутри useEffect
.
const useDataApi = initialUrl => {
const [data, setData] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);
const fetchData = async () => {
setIsError(false);
setIsLoading(true);
try {
const result = await axios(initialUrl);
setData(result.data);
} catch (error) {
setIsError(true);
}
setIsLoading(false);
};
useEffect(() => {
fetchData();
}, []);
return [{ data, isLoading, isError }, fetchData];
};
. Кроме того, для создания приложений такого типа способ, которым я пользуюсь, подойдет или есть другое правильное решение, например, не использовать useEffects
или не создавать какой-либо пользовательский Hook? Спасибо