web-dev-qa-db-ja.com

Effect Hookでaxiosを使用するには?

クラスベースのコンポーネント:

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

無限ループを作成します。 []/{}を2番目の引数[1] [2]として渡すと、それ以降の呼び出しはブロックされます。ただし、配列の更新も防止されます。

[1] seEffectの無限ループ

[2] React useEffectを1回だけ使用してローディング関数を呼び出す方法

6
Mahmudul Haque

useEffectの2番目の引数として空の配列を指定して、最初のレンダリングの後にエフェクトを1回だけ実行することを示します。 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/[email protected]/umd/react.production.min.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>

<div id="root"></div>
5
Tholle

axios-hooks の実装方法を確認できます。

Tholle's answer で説明されているように、それは非常に単純であり、リクエストを行うタイミングとしないタイミングを決定するために提供する構成オブジェクト(またはURL)を使用します。

ステートレスな機能コンポーネントで素晴らしいaxiosを使用できるようにすることに加えて、サーバー側のレンダリングもサポートします。これにより、フックは実装が非常に簡単になります。

免責事項:私はそのパッケージの著者です。

2
Simone

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

結果を見ることができます online

0
int64ago