我的应用程序有一个问题,当我单击新按钮功能时,它会两次重新呈现一个新笑话。这是我的代码:
import React, { useState, useEffect } from "react";
import { Typography, Button } from "@material-ui/core";
import Navigation from "../Navigation";
export default function RandomJoke() {
const [isLoaded, setLoaded] = useState(false);
const [jokeData, setJokeData] = useState({});
const [loadNewJoke, setLoadNewJoke] = useState(false);
function useFetch() {
async function fetchMyAPI() {
let response = await fetch("https://icanhazdadjoke.com/slack");
response = await response.json();
setJokeData(response);
setLoaded(true);
}
useEffect(() => {
fetchMyAPI();
if (loadNewJoke) setLoadNewJoke(false);
}, [loadNewJoke]);
}
useFetch();
function reloadJoke() {
setLoaded(false);
setLoadNewJoke(true);
}
return (
<>
<Navigation mainpage="RandomJoke" />
<Typography variant="h6">Random Dad Joke</Typography>
{isLoaded && <div>{jokeData.attachments[0].text}</div>}
{!isLoaded && <div>loading...</div>}
{isLoaded && (
<Button variant="contained" onClick={() => reloadJoke()}>
New one
</Button>
)}
</>
);
}
我试着添加一个新的笑话状态挂钩,但仍然无法实现。谢谢
只要loadNewJoke
的值发生变化,就会触发useEffect,对吗?不仅仅是当loadNewJoke
设置为true时。仔细查看按下按钮后拨打的电话,以及呼叫setLoadNewJoke
的次数。
尝试移动:
if (loadNewJoke) setLoadNewJoke(false);
在fetchMyApi函数中。我猜当你按下按钮时,你会触发效果,因为在这种情况下,你会将deps值更改为true。然后在效果结束之前,你再次将其更改为false,这将触发你的效果重新运行。但是,为什么你不只是在点击按钮的回调中触发fetchApi,这样你就可以删除1个状态[loadNewJoke-setLoadNewJoke],也会删除useEffect,并使代码在所有上更干净
您使用useEffect错误,我建议您查看挂钩的规则
不要在循环、条件或嵌套函数中调用Hook。
我在回调中遵循了Andom Miltev关于直接触发异步函数的说法,现在它运行顺利-感谢大家的帮助:(
import React, { useState, useEffect } from "react";
import { Typography, Button } from "@material-ui/core";
import Navigation from "../Navigation";
export default function RandomJoke() {
const [isLoaded, setLoaded] = useState(false);
const [jokeData, setJokeData] = useState({});
async function fetchMyAPI() {
setLoaded(false);
let response = await fetch("https://icanhazdadjoke.com/slack");
response = await response.json();
setJokeData(response);
setLoaded(true);
console.log("fired 1");
}
useEffect(() => {
fetchMyAPI();
}, []);
return (
<>
<Navigation mainpage="RandomJoke" />
<Typography variant="h6">Random Dad Joke</Typography>
{isLoaded && <div>{jokeData.attachments[0].text}</div>}
{!isLoaded && <div>loading...</div>}
{isLoaded && (
<Button variant="contained" onClick={() => fetchMyAPI()}>
New one
</Button>
)}
</>
);
}