Где я могу сделать вызов API с хуками в реакции?

В основном мы выполняем вызовы API в методе жизненного цикла componentDidMount() в компонентах класса React, как показано ниже

     componentDidMount(){
          //Here we do API call and do setState accordingly
     }

Но после того, как в React v16.7.0 введены хуки, все они в основном похожи на функциональные компоненты

Мой вопрос: где именно нам нужно сделать вызов API в функциональном компоненте с перехватчиками?

У нас есть какой-нибудь метод для этого, подобный componentDidMount()?

Ответы

Ответ 1

Да, есть аналогичный (но не тот же самый!) Заменитель componentDidMount с хуками, и это хук useEffect.

Другие ответы на самом деле не отвечают на ваш вопрос о том, где вы можете делать вызовы API. Вы можете выполнять вызовы API, используя useEffect и передавая пустой массив или объект в качестве второго аргумента в качестве замены componentDidMount(). Ключ здесь - второй аргумент. Если вы не предоставите пустой массив или объект в качестве второго аргумента, вызов API будет вызываться при каждом рендеринге, и он фактически становится componentDidUpdate.

Как упомянуто в документах:

Передача пустого массива [] входных данных говорит React, что ваш эффект не зависит от каких-либо значений из компонента, так что эффект будет работать только при монтировании и очистке при размонтировании; это не будет работать на обновлениях.

Вот несколько примеров сценариев, в которых вам нужно будет выполнять вызовы API:

Вызов API строго на горе

Попробуйте запустить приведенный ниже код и посмотрите результат.

function User() {
  const [firstName, setFirstName] = React.useState(null);
  const [lastName, setLastName] = React.useState(null);
  
  React.useEffect(() => {
    fetch('https://randomuser.me/api/')
      .then(results => results.json())
      .then(data => {
        const {name} = data.results[0];
        setFirstName(name.first);
        setLastName(name.last);
      });
  }, []); // <-- Have to pass in [] here!

  return (
    <div>
      Name: {!firstName || !lastName ? 'Loading...' : '${firstName} ${lastName}'}
    </div>
  );
}

ReactDOM.render(<User />, document.querySelector('#app'));
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>

<div id="app"></div>

Ответ 2

Вы можете использовать библиотеку, которая предоставляет вам хуки, например https://resthooks.io

Тогда получение ваших данных становится простым:

const article = useResource(ArticleResource.detailShape(), { id });

Теперь вы захватили статью по id. Все несоответствующие пути (загрузка, состояния ошибок) обрабатываются границами Suspense и Error соответственно.

Для начала следуйте этому простому руководству: https://resthooks.io/docs/getting-started/installation

При сжатии всего 7 Кбайт это избавит вас от многих проблем и в конечном итоге уменьшит размер вашего пакета из-за меньшего количества повторяющегося кода.

Ответ 3

Когда вы используете функциональные компоненты с API-интерфейсом ловушек, вы можете использовать метод useEffect() для создания побочных эффектов. Всякий раз, когда состояние обновляется из-за этих побочных эффектов, компонент будет повторно отображаться.

Пример из документов.

import { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    // Update the document title using the browser API
    document.title = 'You clicked ${count} times';
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

Например, вы можете вызвать setCount в функции обратного вызова асинхронного запроса. Когда обратный вызов будет выполнен, состояние будет обновлено, и React выполнит повторную визуализацию компонента. Также из документов:

Совет

Если вы знакомы с методами жизненного цикла класса React, вы можете использовать useEffect Hook как комбинацию componentDidMount, componentDidUpdate и componentWillUnmount.

Ответ 4

Вы также можете использовать use-http как:

import useFetch from 'use-http'

function App() {
  // add whatever other options you would add to 'fetch' such as headers
  const options = {
    method: 'POST',
    body: {}, // whatever data you want to send
  }

  var [data, loading, error] = useFetch('https://example.com', options)

  // want to use object destructuring? You can do that too
  var { data, loading, error } = useFetch('https://example.com', options)

  if (error) {
    return 'Error!'
  }

  if (loading) {
    return 'Loading!'
  }

  return (
    <code>
      <pre>{data}</pre>
    </code>
  )
}