Реагировать крючки использовать эффект - PullRequest
0 голосов
/ 24 февраля 2020

У меня возникла проблема с моим приложением, так как оно дважды отображает новую шутку, когда я нажимаю новую функцию кнопки. Вот мой код:

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

Я попытался добавить хук состояния newjoke, но все еще не смог сработать. Спасибо

Ответы [ 4 ]

1 голос
/ 24 февраля 2020

Этот useEffect срабатывает при изменении значения loadNewJoke, верно? Не только когда loadNewJoke установлено в значение true. Посмотрите внимательно на звонки, сделанные после нажатия кнопки, и сколько раз setLoadNewJoke вызывается.

0 голосов
/ 25 февраля 2020

Я следовал тому, что Andom Miltev сказал о запуске функции asyn c непосредственно в моем обратном вызове, и теперь она работает гладко - спасибо всем за помощь:)

    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>
      )}
    </>
  );
}
0 голосов
/ 24 февраля 2020

Вы используете useEffect неправильно, я предлагаю вам взглянуть на Правила хуков

Не вызывайте хуки внутри циклов, условий или вложенных функций.

0 голосов
/ 24 февраля 2020

Попробуйте переместить:

if (loadNewJoke) setLoadNewJoke(false);

В вашей функции fetchMyApi. Я предполагаю, что когда вы нажмете кнопку, вы активируете эффект, потому что в этом случае вы меняете значение deps на true. Затем, прежде чем эффект закончится, вы снова измените его на false, что вызовет повторный запуск вашего эффекта. Но почему вы не просто запускаете fetchApi в своем обратном вызове при нажатии кнопки, таким образом вы можете удалить 1 состояние [loadNewJoke, setLoadNewJoke], также удалите useEffect и сделаете код чище над всеми

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...