Где я могу сделать вызов API с хуками в реакции? - PullRequest
0 голосов
/ 09 ноября 2018

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

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

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

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

У нас есть какой-нибудь метод, похожий на componentDidMount()?

Ответы [ 4 ]

0 голосов
/ 17 апреля 2019

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

<code>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}
) }
0 голосов
/ 09 ноября 2018

Да, есть аналогичный (но не тот же!) Заменитель 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/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

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

Вызов API всякий раз, когда изменяются реквизит / состояние

Если вы, например, отображаете страницу профиля пользователя, где каждая страница имеет состояние user-prop / prop, вы должны передать этот идентификатор в качестве значения во второй параметр useEffect, чтобы данные были повторно получены для новый идентификатор пользователя. componentDidMount здесь недостаточно, поскольку компонент может не нуждаться в перемонтировании, если вы переходите непосредственно от пользователя A к профилю пользователя B.

Традиционным образом, вы должны сделать:

componentDidMount() {
  this.fetchData();
}

componentDidUpdate(prevProps, prevState) {
  if (prevState.id !== this.state.id) {
    this.fetchData();
  }
}

С крючками это будет:

useEffect(() => {
  this.fetchData();
}, [id]);

Попробуйте запустить приведенный ниже код и посмотрите результат. Например, измените id на 2, чтобы увидеть, что useEffect запускается снова.

function Todo() {
  const [todo, setTodo] = React.useState(null);
  const [id, setId] = React.useState(1);
  
  React.useEffect(() => {
    if (id == null || id === '') {
      return;
    }
    
    fetch(`https://jsonplaceholder.typicode.com/todos/${id}`)
      .then(results => results.json())
      .then(data => {
        setTodo(data);
      });
  }, [id]); // useEffect will trigger whenever id is different.

  return (
    
       setId(e.target.value)}/>
      
{JSON.stringify(todo, null, 2)}
); } ReactDOM.render (, document.querySelector ('# app'));
<script src="https://unpkg.com/react@16.8.1/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.8.1/umd/react-dom.development.js"></script>

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

Вам следует прочитать useEffect, чтобы вы знали, что вы можете / не можете делать с ним.

Захватывающий

Как сказал Дэн Абрамов в этом выпуске GitHub :

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

Так что следите за обновлениями Suspense!

0 голосов
/ 03 марта 2019

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

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

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

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

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

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

0 голосов
/ 09 ноября 2018

Когда вы используете функциональные компоненты с 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, вы можете подумать использования Effect Hook as componentDidMount, componentDidUpdate и componentWillUnmount в сочетании.

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