反应挂钩的使用效果

时间:2020-02-24 20:29:28

标签: javascript reactjs react-hooks

我的应用程序存在问题,因为当我单击新按钮功能时,它会重新渲染一次新笑话。这是我的代码:

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

我尝试添加新笑话状态挂钩,但仍然无法解决。谢谢

4 个答案:

答案 0 :(得分:1)

只要loadNewJoke的值更改,useEffect就会触发,对吗?不只是将loadNewJoke设置为true。仔细查看按下按钮后的通话以及setLoadNewJoke的通话次数。

答案 1 :(得分:0)

尝试移动:

if (loadNewJoke) setLoadNewJoke(false);

在您的fetchMyApi函数中。我猜想当您按下按钮时,会触发效果,因为在这种情况下您将deps值更改为true。然后,在效果结束之前,您将其再次更改为false,这将触发triggeer再次运行您的效果。 但是为什么您不只是在单击按钮时在回调中触发fetchApi,这样您就可以删除1个状态[loadNewJoke,setLoadNewJoke],也将删除useEffect并使整个代码更干净

答案 2 :(得分:0)

您使用useEffect错误,建议您看看Rules of Hooks

请勿在循环,条件或嵌套函数中调用Hooks。

答案 3 :(得分:0)

我遵循了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>
      )}
    </>
  );
}