繁体   English   中英

在 `useEffect()` 中手动调用 api

[英]Calling api manually in `useEffect()`

我对 function 组件的useEffect()有疑问。

此脚本从服务器调用 api 并显示内容。

const NameList = (props) => {
  const [result, setResult] = useState([]);
  useEffect(() => {
    var url =  `http://localhost/blogs`;
    axios.get(url)
    .then((res)=> {
    setResult(res.data.items);
    })
    .catch(err=>{console.log(err);});
  }, []);
  return(  
    <TableBody>
    {
      result.map(item => {
        return (
          <TableRow key={item.id}>
          <TableCell>
          {item.name}
            </TableCell>
          </TableRow>
        )
      })
    }
    </TableBody>  
  );
}

它在页面加载时显示列表(这很棒并且useEffect很有用)。

我想通过手动调用 api 来刷新列表(例如,在另一个组件中单击按钮时等)

我有两个想法。

A)将ajax(axios.get)保留在useEffect()中并以某种方式从按钮调用useEffect()

B)在useEffect()之外制作新的 function 包括ajax并从 button 和useEffect()调用它。

我可能仍然对如何使用useEffect()

我很欣赏哪一个是最佳实践的建议,我该如何做到这一点。

谢谢你。

创建一个新的 state 变量,例如。 刷新。

 const [refresh, setRefresh] = useState(false);

每当您希望调用 useEffect 时更新刷新变量,例如在您的 onClick 处理程序内部

  setRefresh(!refresh);

添加刷新到 useEffect 依赖数组,在最后一行使用效果

 }, [refresh]);

现在 useEffect 像现在一样在第一次渲染时被调用,并且每次刷新 state 变量都会发生变化。

如果您之前使用过 class 组件,那么 useEffect 是生命周期方法的组合:componentDidMount()、componentDidUpdate() 和 componentWillUnmount()。 如果被跟踪的数组中没有任何被跟踪的状态,则 useEffect 仅在组件第一次挂载时触发,其效果与 componentDidMount() 相同。

所以选项B好,在外面定义function,第一次挂载的时候在useEffect中使用:

function getData() {
    var url =  `http://localhost/blogs`;
    axios.get(url)
    .then((res)=> {
    setResult(res.data.items);
    })
    .catch(err=>{console.log(err);});
}

useEffect(() => {
    getData()
},[])

然后使用单独的按钮触发 function:

<button onClick={getData}>Get Data</button

因此,如果您希望在重新加载时获取数据, useEffect已经处理好了,如果您要添加自定义按钮,建议有一个单独的 function 返回一个 promise,然后您可以轻松地将其放入useEffect function 等待它,也减少冗余,这样更有效率

...
// to get the data incase of conditions where we only need data and state change is not required
function functionName(){
    return new Promise((resolve, reject)=>{
        var url =  `http://localhost/blogs`;
        axios.get(url)
        .then((res)=> {
        resolve(res.data.items);
        })
        .catch(err=>{reject(err);});
    })
}
// to handle the refresh button click, 
// wire the function below to any button onClick so that refresh process will be done.
function manualRefreshOperation(){
    functionName()
    .then((res)=> {
    setResult(res);
    })
    .catch(err=>{console.log(err);});
}

useEffect(() => {
    manualRefreshOperation();
  }, []);

此过程有助于减少冗余,并确保您可以将其链接到任何 function

您不能手动调用 useEffect。 Go with option B. Define the ajax call in a separate function and then call this function both in useEffect and in your button's onClick callback. 您唯一可以做的另一件事是,如果 state 在用户单击按钮时发生变化,那么您可以将该 state 变量放入 useEffect 的依赖数组中,因为它将在组件安装时调用,并且当 Z9ED39E2886A73A 变量发生变化时会调用它。

B) 在 useEffect() 之外创建新的 function 包括 ajax 并从按钮和 useEffect() 调用它。

这是一个好主意。 您可以将数据获取代码抽象为 function,您可以在效果和其他地方(例如在另一个事件处理程序中)调用它。

在这里,我将它附加到刷新按钮上的单击处理程序。

import { useState, useEffect } from "react";
import axios from "axios";

var url = `https://rickandmortyapi.com/api/character`;

const NameList = () => {
  const [result, setResult] = useState([]);
  const [loading, setloading] = useState(false);
  const [error, seterror] = useState("");
  
  const fetchData = () => {
    setloading(true);

    // get 3 random characters
    const characters = [...Array(3)].map(() => (Math.random() * 183) | 0);
    axios
      .get(`${url}/${characters}`)
      .then((res) => {
        setResult(res.data);
        seterror("");
      })
      .catch((err) => {
        seterror(err.message);
      })
      .finally(() => {
        setloading(false);
      });
  };

  useEffect(() => {
    fetchData();
  }, []);
  return (
    <>
      <button onClick={() => fetchData()}>refresh</button>
      {error ? (
        <p>{error}</p>
      ) : loading ? (
        <p>"loading..."</p>
      ) : (
        <table>
          <tbody>
            {result.map((item) => {
              return (
                <tr key={item.id}>
                  <td>{item.name}</td>
                </tr>
              );
            })}
          </tbody>
        </table>
      )}
    </>
  );
};

export default NameList;

编辑勇敢的dijkstra-tkoy3

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM