在哪里可以通过钩子进行API调用? [英] Where can I make API call with hooks in react?

查看:38
本文介绍了在哪里可以通过钩子进行API调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上,我们在如下所示的React类组件的componentDidMount()生命周期方法中进行API调用

Basically we do API calls in componentDidMount() life cycle method in React class components like below

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

但是在React v16.7.0中引入了钩子之后,其大部分都类似于功能组件

But after hooks are introduced in React v16.7.0, its all like functional components mostly

我的查询是,我们到底需要在带有钩子的功能组件中进行API调用吗?

My query is, where exactly do we need to make API call in functional component with hooks?

我们有没有类似componentDidMount()的方法?

Do we have any method for it similar like componentDidMount()?

推荐答案

是的,带有钩子的componentDidMount有类似(但不相同!)的替代品,它是useEffect钩子.

Yes, there's a similar (but not the same!) substitute for componentDidMount with hooks, and it's the useEffect hook.

其他答案并不能真正回答您在哪里可以进行API调用的问题.您可以使用useEffect传入空数组或对象作为第二个参数来代替componentDidMount(),从而进行API调用.这里的关键是第二个参数.如果您不提供空数组或对象作为第二个参数,则将在每个渲染器上调用API调用,并且该调用将有效地变为componentDidUpdate.

The other answers don't really answer your question about where you can make API calls. You can make API calls by using useEffect and passing in an empty array or object as the second argument as a replacement for componentDidMount(). The key here is the second argument. If you don't provide an empty array or object as the second argument, the API call will be called on every render, and it effectively becomes a componentDidUpdate.

如文档中所述:

传入空数组[]会告诉React您的效果不依赖于组件中的任何值,因此该效果仅在安装时运行,而在卸载时清除;它不会在更新上运行.

Passing in an empty array [] of inputs tells React that your effect doesn’t depend on any values from the component, so that effect would run only on mount and clean up on unmount; it won’t run on updates.

以下是一些需要进行API调用的场景的示例:

Here are some examples for scenarios where you will need to make API calls:

尝试运行下面的代码并查看结果.

Try running the code below and see the result.

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>

例如,如果要显示某个用户的个人资料页面,其中每个页面都有一个userID状态/属性,则应将该ID作为值传递给useEffect的第二个参数,以便重新获取数据新的用户ID. componentDidMount在这里是不够的,因为如果您直接从用户A转到用户B的配置文件,则可能不需要重新安装组件.

If you are for example displaying a profile page of a user where each page has a userID state/prop, you should pass in that ID as a value into the second parameter of useEffect so that the data will be refetched for a new user ID. componentDidMount is insufficient here as the component might not need remounting if you go directly from user A to user B's profile.

以传统的课堂方式,您可以这样做:

In the traditional classes way, you would do:

componentDidMount() {
  this.fetchData();
}

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

带有钩子的是:

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

尝试运行以下代码,然后查看结果.例如,将id更改为2,以查看useEffect再次运行.

Try running the code below and see the result. Change the id to 2 for instance to see that useEffect is run again.

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 (
    <div>
      <input value={id} onChange={e => setId(e.target.value)}/>
      <br/>
      <pre>{JSON.stringify(todo, null, 2)}</pre>
    </div>
  );
}

ReactDOM.render(<Todo />, 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 可以/不能使用它.

You should read up on useEffect so that you know what you can/cannot do with it.

如丹·阿布拉莫夫(Dan Abramov)在本GitHub问题上所说的:

As Dan Abramov said on this GitHub Issue:

从长远来看,我们将不鼓励这种(useEffect)模式,因为它会鼓励比赛条件.例如-在通话开始和结束之间可能会发生任何事情,并且您可能会获得新的道具.相反,我们建议使用Suspense进行数据提取

Longer term we'll discourage this (useEffect) pattern because it encourages race conditions. Such as — anything could happen between your call starts and ends, and you could have gotten new props. Instead, we'll recommend Suspense for data fetching

所以请继续关注悬念!

这篇关于在哪里可以通过钩子进行API调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆