Как использовать axios в Effect Hook? - PullRequest
0 голосов
/ 05 ноября 2018

В компоненте на основе класса:

componentDidMount() {
    axios.get('https://jsonplaceholder.typicode.com/posts').then((res) => {
        this.setState({
            posts: res.data.slice(0, 10)
        });
        console.log(posts);
    })
}

Я пробовал это:

const [posts, setPosts] = useState([]);

useEffect(() => {
    axios.get('https://jsonplaceholder.typicode.com/posts').then((res) => {
        setPosts(res.data.slice(0, 10));
        console.log(posts);
    })
});

Создает бесконечный цикл. Если я передам [] / {} в качестве второго аргумента [1] [2], то он блокирует дальнейший вызов. Но это также препятствует обновлению массива.

[1] Используется бесконечный циклЭффект

[2] Как вызвать функцию загрузки с использованием React useEffect только один раз

Ответы [ 3 ]

0 голосов
/ 19 декабря 2018

Я написал пользовательских хуков для Axios.js.

Вот пример:

import React, { useState } from 'react';

import useAxios from '@use-hooks/axios';

export default function App() {
  const [gender, setGender] = useState('');
  const {
    response,
    loading,
    error,
    query,
  } = useAxios({
    url: `https://randomuser.me/api/${gender === 'unknow' ? 'unknow' : ''}`,
    method: 'GET',
    options: {
      params: { gender },
    },
    trigger: gender,
    filter: () => !!gender,
  });

  const { data } = response || {};

  const options = [
    { gender: 'female', title: 'Female' },
    { gender: 'male', title: 'Male' },
    { gender: 'unknow', title: 'Unknow' },
  ];

  if (loading) return 'loading...';
  return (
    <div>
      <h2>DEMO of <span style={{ color: '#F44336' }}>@use-hooks/axios</span></h2>
      {options.map(item => (
        <div key={item.gender}>
          <input
            type="radio"
            id={item.gender}
            value={item.gender}
            checked={gender === item.gender}
            onChange={e => setGender(e.target.value)}
          />
          {item.title}
        </div>
      ))}
      <button type="button" onClick={query}>Refresh</button>
      <div>
        {error ? error.message || 'error' : (
          <textarea cols="100" rows="30" defaultValue={JSON.stringify(data || {}, '', 2)} />
        )}
      </div>
    </div>
  );
}

Вы можете увидеть результат онлайн .

0 голосов
/ 18 февраля 2019

Вы можете проверить, как реализовано axios-hooks .

Это очень просто и использует предоставленный вами объект конфигурации (или URL), чтобы решить, когда делать запрос, а когда нет, как объяснено в ответ Толле .

В дополнение к тому, что вы можете использовать удивительные axios в ваших функциональных компонентах без сохранения состояния, он также поддерживает рендеринг на стороне сервера, что, как выясняется, позволяет легко реализовать хуки.

Отказ от ответственности: я являюсь автором этого пакета.

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

Предоставление пустого массива в качестве второго аргумента для useEffect, указывающего, что вы хотите, чтобы эффект запускался один раз после того, как начальный рендеринг - это путь. Причина, по которой console.log(posts); показывает пустой массив, состоит в том, что переменная posts все еще ссылается на исходный массив, а setPosts также асинхронный, но он все равно будет работать так, как вы хотите, если будете использовать его при рендеринге.

Пример

const { useState, useEffect } = React;

function App() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    setTimeout(() => {
      setPosts([{ id: 0, content: "foo" }, { id: 1, content: "bar" }]);
      console.log(posts);
    }, 1000);
  }, []);

  return (
    <div>{posts.map(post => <div key={post.id}>{post.content}</div>)}</div>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.production.min.js"></script>

<div id="root"></div>
...