Как использовать методы / функции жизненного цикла в React Hook?

Что не так со следующим компонентом? Выдает ошибку, в то время как исходная версия на основе класса с методами жизненного цикла работает нормально?

import React, { useState, useEffect } from "react";
import axios from "axios";
const  NewsHook = ()=> {
  const [mount, setMount] = useState(false);
  const [news, setNews] = useState([]);
  useEffect(() => {
    setMount(true);
    axios.get('https://hn.algolia.com/api/v1/search?query=react')
        .then(result => {
                if (mount){
                    setNews({
                        news: result.data.hits,
                    })
                }
            }
        );
    return () => {
      setMount(false);
   }
  }, [mount]);

  return (
        <ul>
            {news.map(topic => (
                <li key={topic.objectID}>{topic.title}</li>
            ))}
        </ul>
  );
}
export default NewsHook

3 ответа

Решение было следующее:

setNews(result.data.hits);

Вам не нужно устанавливать состояние монтирования, потому что useEffect будет работать автоматически, когда компонент монтируется, и если вы хотите, чтобы он работал только с одним, вы добавляете пустой array [] в качестве второго аргумента

и вам нужно обернуть свой запрос Axios внутри useEffect в такую ​​асинхронную функцию:

import React, { useState, useEffect } from "react";
import axios from "axios";

const  NewsHook = ()=> {
  const [news, setNews] = useState([]);

  useEffect(() => {
    const getNews = async () => {
      const result  = await axios.get('https://hn.algolia.com/api/v1/search?query=react');
      setNews({
        news: result.data.hits,
      })
    };
    getNews();
  }, []);

  return (
    <ul>
      {news.map(topic => (
        <li key={topic.objectID}>{topic.title}</li>
       ))}
    </ul>
  );
};

export default NewsHook

Проблема в том, что данные загружаются. Так что новости по-прежнему будут нулевыми. Либо с помощью async для решения проблемы, либо таким образом:)

import React, { useEffect, useState } from "react";
import axios from "axios";
import "./styles.css";

export default function App() {
  const [mount, setMount] = useState(false);
  const [news, setNews] = useState([{ new: null }]);

  useEffect(() => {
    setMount(true);
    axios
      .get("https://hn.algolia.com/api/v1/search?query=react")
      .then(result => {
        setNews({ new: result.data.hits });
      });

    return () => {
      setMount(false);
    };
  }, [mount]);

  return (
    <div>
      <ul>
        {news.new == null ? (
          <h2>Loading</h2>
        ) : (
          news.new.map(item => {
            return <li key={item.objectID}>{item.title}</li>;
          })
        )}
      </ul>
    </div>
  );
}

это решит вашу проблему. Надеюсь, это поможет:)

Другие вопросы по тегам