简体   繁体   English

React 钩子使用效果

[英]React hooks useeffect

I am having an issue with my app in that it re renders a new joke twice when I click the new button function.我的应用程序存在问题,因为当我单击新按钮功能时,它会重新呈现一个新笑话两次。 Here is my code:这是我的代码:

    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>
      )}
    </>
  );
}

I tried adding a newjoke state hook but still couldn't work it out.我尝试添加一个 newjoke 状态挂钩,但仍然无法解决。 Thank you谢谢

That useEffect fires whenever the value of loadNewJoke changes, right?这useEffect火灾时的值loadNewJoke变化,对不对? Not just when loadNewJoke is set to true.不仅仅是当loadNewJoke设置为 true 时。 Look closely at the calls made after a button press, and how many times setLoadNewJoke is called.仔细查看按下按钮后发出的调用,以及调用setLoadNewJoke次数。

Try to move:尝试移动:

if (loadNewJoke) setLoadNewJoke(false);

In your fetchMyApi function.在您的 fetchMyApi 函数中。 I'm guessing when you hit the button, you trigger the effect cuz u change you deps value in this case to true.我猜当你按下按钮时,你会触发效果,因为你在这种情况下将 deps 值更改为 true。 Then before effect is over you change it again to false which will triggeer re-run on your effect.然后在效果结束之前,您再次将其更改为 false,这将触发您的效果重新运行。 But why you dont just trigger fetchApi in your callback on button click, this way you can remove 1 state [loadNewJoke, setLoadNewJoke], will also remove the useEffect and make code cleaner over all但是为什么你不只是在按钮点击的回调中触发 fetchApi,这样你就可以删除 1 个状态 [loadNewJoke, setLoadNewJoke],也将删除 useEffect 并使代码更清晰

You're using useEffect wrong, i suggest u take a look at the Rules of Hooks你使用 useEffect 错了,我建议你看看Hooks规则

Don't call Hooks inside loops, conditions, or nested functions.不要在循环、条件或嵌套函数中调用 Hook。

I followed what Andom Miltev said about triggering the async function directly in my callback and it now works smoothly - thank you everyone for the help :)我按照 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>
      )}
    </>
  );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM