在 React 组件中执行 Promise
介绍
当您需要在 React 组件中执行异步代码时,通常会涉及 Javascript 承诺。确保您的组件在承诺完成时更新一开始并不完全明显,因此在本指南中,我将向您展示如何在 React 组件中使用承诺。
在类组件中处理承诺
在 React 中创建组件时,有两个选项:类组件或功能组件。使用类组件意味着您的组件将自动具有状态的概念,以及组件生命周期方法。
      import React from "react";
class UserComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      email: "",
      password: ""
    };
  }
  componentDidMount() {}
  componentShouldUpdate() {}
  componentWillUnmount() {}
  render() {
    return (
      <div>
        <h1>A user</h1>
      </div>
    );
  }
}
    
组件生命周期方法很重要,因为您需要在其中处理异步代码。具体来说,当 Promise 解析时,可以使用componentDidMount方法用新状态更新组件。具体操作如下:
      import React from "react";
class UserComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      email: "",
      password: ""
    };
  }
  componentDidMount() {
    const fetchUserEmail = async () => {
      const response = await fetch("/emails");
      const { email } = await response.json();
      this.setState({
        email
      });
    };
    fetchUserEmail();
  }
  render() {
    return (
      <div>
        <h1>A user</h1>
        <p>{this.state.email}</p>
      </div>
    );
  }
}
    
在上面的代码片段中,我从一个虚构的端点获取电子邮件,该端点返回一个具有email属性的对象。我使用async/await语法来处理fetch返回的 promise ,以及通过在响应上调用json()返回的 promise 。我从生成的 json 中解构了email属性,并调用this.setState以确保我们使用this.state.email的新值更新组件。
无需使用componentDidMount来处理承诺。如果您只希望承诺在组件加载时执行一次,请使用componentDidMount 。您可以在用户单击按钮时执行相同的承诺。例如:
      import React from "react";
class UserComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      email: "",
      password: ""
    };
  }
  handleButtonClick = () => {
    const fetchUserEmail = async () => {
      const response = await fetch("/emails");
      const { email } = await response.json();
      this.setState({
        email
      });
    };
    fetchUserEmail();
  };
  render() {
    return (
      <div>
        <h1>A user</h1>
        <p>{this.state.email}</p>
        <button onClick={this.handleButtonClick}>Fetch Email</button>
      </div>
    );
  }
}
    
使用 useEffect Hook 处理 Promise
如果您不使用类组件而使用函数组件,则过程非常相似。最大的区别在于如何处理生命周期以及如何使用状态。函数组件没有生命周期方法,但它们确实允许您控制组件的更新时间。我们不必考虑“如何在组件安装时复制更新组件?”,而是考虑“当某些值发生变化时如何更新组件?”对于此功能,我们将使用useEffect钩子。函数组件中也没有this.setState。我们能够使用useState钩子来提供您的组件状态。如下所示:
      import React from "react";
const UserComponent = props => {
  const [email, setEmail] = React.useState("");
  React.useEffect(() => {
    const fetchUserEmail = async () => {
      const response = await fetch("/emails");
      const { email } = await response.json();
      setEmail(email);
    };
    fetchUserEmail();
  }, []);
  return (
    <div>
      <h1>A user</h1>
      <p>{email}</p>
    </div>
  );
};
    
useEffect钩子接受两个参数:第一个参数是函数,第二个参数是依赖项数组。依赖项数组接受一个列表值,当其中任何一个值发生变化时,您作为第一个参数传递的函数就会运行。如果您没有向依赖项数组传递任何值,则该函数只会在组件加载时运行一次。这与 componentDidMount生命周期方法的行为类似。
您正在使用以下行创建一个名为email 的状态变量:
      const [email, setEmail] = React.useState("");
    
useState始终返回一个包含两个值的数组:当前状态值和更新函数,始终按此顺序排列。这意味着我们可以像上面那样解构该数组。将空字符串传递给useState意味着我们将email的值默认为空字符串。调用setEmail就像在类组件中调用this.setState一样。组件将使用新的email值重新渲染。
与类组件示例类似,您并不总是必须在useEffect钩子中处理承诺。
      import React from "react";
const UserComponent = props => {
  const [email, setEmail] = React.useState("");
  const fetchUserEmail = async () => {
    const response = await fetch("/emails");
    const { email } = await response.json();
    setEmail(email);
  };
  return (
    <div>
      <h1>A user</h1>
      <p>{email}</p>
      <button onClick={fetchUserEmail}>Fetch Email</button>
    </div>
  );
};
    
在上面的例子中,我们在点击“获取电子邮件”按钮时触发获取承诺。当承诺解析时,我们将使用新的电子邮件地址调用setEmail 。
结论
类组件和函数组件在使用 Promise 时略有不同。在本指南中,我们介绍了两种常见情况:在组件挂载时处理 Promise 和在用户执行操作时处理 Promise。现在您已经学会了如何使用它们,我希望您尝试在下一个项目中添加 Promise 😊。
查看我的课程Javascript 生成器和迭代器以了解有关 Javascript 核心语言的更多信息。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
 
                                 
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                 
                             
                                     
                                     
                                     
                                     
     
    
 
             
   
        
请先 登录后发表评论 ~