反应useEffect以加载数据

时间:2019-11-13 04:32:06

标签: reactjs

我正在学习React Hooks,并且想知道什么是“钩子友好”时重新加载数据的最有效方法。

我确定了3个用例(最新的显然是“更合适的”

使用已复制的代码

//Example of Using useEffect Hooks by duplicating code
import React, {useState, useEffect} from 'react'
import axios from 'axios'

export default () => {
  const [deals, setDeals] = useState([])
  const [loading, setLoading] = useState(false)

  useEffect(() => {
    setLoading(true)
    axios({
      method: 'GET',
      url: `http://localhost:1338/deals`
    }).then(res => {
      setDeals(res.data)
      setLoading(false)
    })
  }, [setDeals])
  return(
    <div className="Deals">
      {loading &&
        <p>It's loading</p>
      }
      {!loading &&
        <>
          {deals.map((deal, i) => (
            <div key={i} className="Deal Note">
              {deal.label}
            </div>
          ))}
        </>
      }

      <button onClick={() => {
          setLoading(true)
          axios({
            method: 'GET',
            url: `http://localhost:1338/deals`
          }).then(res => {
            setDeals(res.data)
            setLoading(false)
          }).catch(res => {
            setDeals([{label: 1, label: 2}])
            setLoading(false)
          })
      }}>Fetch Again</button>

    </div>
  )
}

通过在外部函数内部传递钩子。代码重用-在另一个函数中使用钩子 我了解这不是使用钩子的“方式”,尽管这是我的第一个首选解决方案

//Example of Using useEffect Hooks by feeding hooks to external function
import React, {useState, useEffect} from 'react'
import axios from 'axios'

const usefetchMore = (setDeals, setLoading) => {
  console.log("usefetchMore")
  setLoading(true)
  axios({
    method: 'GET',
    url: `http://localhost:1338/deals`
  }).then(res => {
    setDeals(res.data)
    setLoading(false)
  })
}

export default () => {
  const [deals, setDeals] = useState([])
  const [loading, setLoading] = useState(false)

  useEffect(() => {
    usefetchMore(setDeals, setLoading)
  }, [setDeals])

  return(
    <div className="Deals">
      {loading &&
        <p>It's loading</p>
      }
      {!loading &&
        <>
          {deals.map((deal, i) => (
            <div key={i} className="Deal Note">
              {deal.label}
            </div>
          ))}
        </>
      }

      <button onClick={() => usefetchMore(setDeals, setLoading)}>Fetch Again</button>

    </div>
  )
}

这似乎是“正确的做法”,它基于重新触发useEffect,因为它正在监听reload变量的更改,该变量只是为了重新触发它。

//Example of Using useEffect Hooks with variable to re-trigger useEffect
import React, {useState, useEffect} from 'react'
import axios from 'axios'
/* DOESN't WORK */
export default () => {
  const [deals, setDeals] = useState([])
  const [loading, setLoading] = useState(false)
  const [reload, setReload] = useState(0)
  useEffect(() => {
    console.log("Deal4.useEffect")
    setLoading(true)
    axios({
      method: 'GET',
      url: `http://localhost:1338/deals`
    }).then(res => {
      setDeals(res.data)
      setLoading(false)
    })
  }, [setDeals, reload])
  return(
    <div className="Deals">
      {loading &&
        <p>It's loading</p>
      }
      {!loading &&
        <>
          {deals.map((deal, i) => (
            <div key={i} className="Deal Note">
              {deal.label}
            </div>
          ))}
        </>
      }

      <button onClick={() => {
          setReload(reload + 1)
      }}>Fetch Again</button>
    </div>
  )
}

我的问题是:如果我要构建一个显示加载并允许刷新的组件,那用“ React hooks”编写它的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

在/ src /中创建一个名为Photos.js的组件,并为其提供基本列表:

 import React from "react";
import { useFetch } from "./hooks";
function Photos() {
  const [data, loading] = useFetch(
    "https://jsonplaceholder.typicode.com/photos?albumId=1"
  );
  return (
    <>
      <h1>Photos</h1>
      {loading ? (
        "Loading..."
      ) : (
        <ul>
          {data.map(({ id, title, url }) => (
            <li key={`photo-${id}`}>
              <img alt={title} src={url} />
            </li>
          ))}
        </ul>
      )}
    </>
  );
}
export default Photos;

现在我们需要一个挂钩!在同一目录中创建一个名为hooks.js的文件,并使用以下文件填充该文件:

    import { useState, useEffect } from "react";
       function useFetch(url) {
        const [data, setData] = useState([]);
        const [loading, setLoading] = useState(true);
  async function fetchUrl() {
    const response = await fetch(url);
    const json = await response.json();
    setData(json);
    setLoading(false);
  }
  useEffect(() => {
    fetchUrl();
  }, []);
  return [data, loading];
}
export { useFetch };

将“照片”组件导入App.js,然后开始执行yarn。完成!