当前位置: 首页 > news >正文

【react】在react中async/await一般用来实现什么功能

在 React 开发中,async/await 是处理异步操作的强大工具,尤其适用于需要等待后台任务完成后再更新 UI 的场景。以下是 8 种典型应用场景和对应的代码示例:

1. 数据获取 (API 请求)

从服务器获取数据是最常见的异步操作场景。

import React, { useState, useEffect } from 'react';

const DataFetcher = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch('https://api.example.com/data');
        if (!response.ok) {
          throw new Error('Network response was not ok');
        }
        const jsonData = await response.json();
        setData(jsonData);
      } catch (error) {
        setError(error.message);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, []);

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;
  return <div>{JSON.stringify(data)}</div>;
};

export default DataFetcher;

2. 表单提交

处理表单提交时,使用 async/await 等待服务器响应。

import React, { useState } from 'react';

const AsyncForm = () => {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [status, setStatus] = useState('idle');

  const handleSubmit = async (e) => {
    e.preventDefault();
    setStatus('submitting');
    try {
      const response = await fetch('https://api.example.com/submit', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ name, email }),
      });
      if (!response.ok) {
        throw new Error('Failed to submit');
      }
      setStatus('success');
    } catch (error) {
      setStatus(`Error: ${error.message}`);
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
        placeholder="Name"
      />
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="Email"
      />
      <button type="submit" disabled={status === 'submitting'}>
        {status === 'submitting' ? 'Submitting...' : 'Submit'}
      </button>
      {status === 'success' && <div>Submitted successfully!</div>}
      {status.startsWith('Error') && <div>{status}</div>}
    </form>
  );
};

export default AsyncForm;

3. 异步状态管理

在组件中管理异步状态。

import React, { useState } from 'react';

const AsyncStateExample = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  const fetchData = async () => {
    try {
      const response = await fetch('https://api.example.com/data');
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
      const jsonData = await response.json();
      setData(jsonData);
    } catch (error) {
      console.error('Error fetching data:', error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      <button onClick={fetchData} disabled={loading}>
        {loading ? 'Loading...' : 'Fetch Data'}
      </button>
      {data && <div>{JSON.stringify(data)}</div>}
    </div>
  );
};

export default AsyncStateExample;

4. 异步路由切换

在使用 React Router 时,完成异步操作后再切换路由。

import React, { useState } from 'react';
import { useHistory } from 'react-router-dom';

const AsyncRouteExample = () => {
  const [username, setUsername] = useState('');
  const history = useHistory();

  const handleLogin = async () => {
    try {
      await new Promise((resolve) => setTimeout(resolve, 1000));
      history.push('/dashboard');
    } catch (error) {
      console.error('Login failed:', error);
    }
  };

  return (
    <div>
      <input
        type="text"
        value={username}
        onChange={(e) => setUsername(e.target.value)}
        placeholder="Username"
      />
      <button onClick={handleLogin}>Login</button>
    </div>
  );
};

export default AsyncRouteExample;

5. 异步数据预加载

在组件渲染前预加载数据。

import React, { useState, useEffect } from 'react';

const AsyncDataPreload = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const preloadData = async () => {
      try {
        const response = await fetch('https://api.example.com/data');
        if (!response.ok) {
          throw new Error('Network response was not ok');
        }
        const jsonData = await response.json();
        setData(jsonData);
      } catch (error) {
        console.error('Error preloading data:', error);
      } finally {
        setLoading(false);
      }
    };

    preloadData();
  }, []);

  if (loading) return <div>Loading data...</div>;
  return <div>{JSON.stringify(data)}</div>;
};

export default AsyncDataPreload;

6. 第三方 API 调用

与浏览器 API 或第三方 SDK 交互。

async function getGeolocation() {
  return new Promise((resolve, reject) => {
    navigator.geolocation.getCurrentPosition(resolve, reject);
  });
}

function LocationButton() {
  const [position, setPosition] = useState(null);

  const handleClick = async () => {
    try {
      const pos = await getGeolocation();
      setPosition({
        lat: pos.coords.latitude,
        lng: pos.coords.longitude
      });
    } catch (err) {
      alert('无法获取位置信息');
    }
  };

  return (
    <div>
      <button onClick={handleClick}>获取当前位置</button>
      {position && <Map coordinates={position} />}
    </div>
  );
}

7. 文件上传/下载

处理文件上传并跟踪进度。

import axios from 'axios';

function FileUploader() {
  const [progress, setProgress] = useState(0);

  const uploadFile = async (file) => {
    const formData = new FormData();
    formData.append('file', file);

    await axios.post('/api/upload', formData, {
      onUploadProgress: (e) => {
        setProgress(Math.round((e.loaded * 100) / e.total));
      }
    });
  };

  return (
    <div>
      <input type="file" onChange={e => uploadFile(e.target.files[0])} />
      {progress > 0 && <ProgressBar value={progress} />}
    </div>
  );
}

8. 路由导航拦截

防止用户在有未保存更改时离开页面。

import { useNavigate, useLocation } from 'react-router-dom';

function EditArticle() {
  const [isDirty, setIsDirty] = useState(false);
  const navigate = useNavigate();

  useEffect(() => {
    const unblock = navigate.block((tx) => {
      if (isDirty && !window.confirm('有未保存的更改,确定离开?')) {
        tx.retry();
      }
    });
    return () => unblock();
  }, [isDirty]);

  const saveArticle = async () => {
    await fetch('/api/articles', { method: 'PUT' });
    setIsDirty(false);
    navigate('/articles');
  };

  return (/* 编辑器 UI */);
}

关键注意事项

  1. 组件卸载时的处理useEffect 中使用标志位避免组件卸载后的状态更新。

useEffect(() => {
  let isMounted = true;
  
  const fetchData = async () => {
    const data = await fetch('/api/data');
    if (isMounted) setData(data);
  };

  fetchData();
  return () => { isMounted = false; };
}, []);
  1. 错误处理 捕获并处理异步操作中的错误,避免未处理的承诺拒绝。

try {
  await fetchData();
} catch (error) {
  if (error.name !== 'AbortError') {
    showErrorToast(error.message);
  }
}
  1. 防抖优化 对频繁触发的异步操作使用防抖。

const search = useDebouncedCallback(async (query) => {
  const results = await fetchResults(query);
  setResults(results);
}, 500);

通过以上示例和注意事项,可以全面了解在 React 中如何使用 async/await 处理各种异步场景,提升应用的响应性和用户体验。

React 中 async/await 的典型应用场景包括:

  1. 网络请求(GET/POST/PUT/DELETE)

  2. 文件操作(上传/下载)

  3. 浏览器 API 调用(地理位置/摄像头)

  4. 定时任务(延迟执行)

  5. WebSocket 通信

  6. 数据库操作(IndexedDB)

  7. 动画序列控制

  8. 第三方库集成(支付 SDK)

合理使用异步操作可以使:

  • 代码逻辑更清晰(避免回调地狱)

  • 错误处理更直观(try/catch 统一捕获)

  • 用户体验更友好(加载状态/进度提示)

码字不易,各位大佬点点赞呗

相关文章:

  • 动态规划二维费用的背包系列一>一和零
  • 【CXX-Qt】5.1 CXX-Qt 构建系统
  • Go 代理爬虫
  • 《基于SpringBoot的图书网购平台的设计与实现》开题报告
  • leetcode11.盛水最多的容器
  • 「Unity3D」使用C#获取Android虚拟键盘的高度
  • hackmyvm-immortal
  • PCL 1.12.0 释放std::free(ptr)问题解决
  • 3.25-2request库
  • Sublime全局搜索快捷键Ctrl+Shift+F不能使用解决
  • react中 useEffect和useLayoutEffect的区别
  • ANYmal Parkour: Learning Agile Navigation for Quadrupedal Robots
  • 使用go实现下载导入Excel模板
  • 2025年- G29-Lc103-3. 最长无重复字符的子字符串--java版
  • PHP接口开发:从基础到高级的全面指南
  • 算法题(107):function
  • Windows 10/11 使用 VSCode + SSH 免密远程连接 Ubuntu 服务器(指定端口)
  • matlab使用fmincon开加速
  • 光电效应及普朗克常数的测定数据处理 Python实现
  • 时隔多年,终于给它换了皮肤,并正式起了名字
  • 做队徽的网站/软文代写新闻稿
  • 网站建设推广服务/创建网站平台
  • 中介网站怎么做/如何进行网络推广
  • 网建设门户网站/中山做网站推广公司
  • 做网站需要做哪些东西/成都网站seo设计
  • 国内网站是cn还是com/seo确定关键词