You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React项目中使用try/catch处理Axios请求错误

解决React注册表单Axios错误:添加try/catch捕获与调试

针对注册表单提交时遇到的Axios错误,通过try/catch语句捕获异步请求异常,同时添加前端校验和错误状态提示,即可实现错误处理与调试。以下是修改后的完整代码:

import React, { useState } from 'react';
import Cookies from 'universal-cookie';
import axios from 'axios';

import signinImage from '../assets/signup.jpg';

const cookies = new Cookies();

const initialState = {
    fullName: '',
    username: '',
    password: '',
    confirmPassword: '',
    phoneNumber: '',
    avatarURL: '',
}

const Auth = () => {
    const [form, setForm] = useState(initialState);
    const [isSignup, setIsSignup] = useState(true);
    // 新增错误状态,用于显示用户提示
    const [error, setError] = useState('');

    const handleChange = (e) => {
        // 输入时清空错误提示
        if (error) setError('');
        setForm({ ...form, [e.target.name]: e.target.value });
    }

    const handleSubmit = async (e) => {
        e.preventDefault();
        setError('');

        // 注册前先校验密码一致性
        if (isSignup && form.password !== form.confirmPassword) {
            setError('密码和确认密码不匹配');
            return;
        }

        const { username, password, phoneNumber, avatarURL } = form;
        const URL = 'https://localhost:5000/auth';
        // const URL = 'https://medical-pager.herokuapp.com/auth';

        try {
            const { data: { token, userId, hashedPassword, fullName } } = await axios.post(
                `${URL}/${isSignup ? 'signup' : 'login'}`, 
                { username, password, fullName: form.fullName, phoneNumber, avatarURL }
            );

            cookies.set('token', token);
            cookies.set('username', username);
            cookies.set('fullName', fullName);
            cookies.set('userId', userId);

            if(isSignup) {
                cookies.set('phoneNumber', phoneNumber);
                cookies.set('avatarURL', avatarURL);
                cookies.set('hashedPassword', hashedPassword);
            }

            window.location.reload();
        } catch (err) {
            // 捕获错误并设置用户提示,同时打印详细日志用于调试
            console.error('请求错误详情:', err);
            setError(err.response?.data?.message || '请求失败,请稍后重试');
        }
    }

    const switchMode = () => {
        setIsSignup((prevIsSignup) => !prevIsSignup);
        // 切换模式时清空错误提示
        setError('');
    }

    return (
        <div className="auth__form-container">
            <div className="auth__form-container_fields">
                <div className="auth__form-container_fields-content">
                    <p>{isSignup ? 'Sign Up' : 'Sign In'}</p>
                    {/* 渲染错误提示 */}
                    {error && <p style={{color: 'red', marginBottom: '1rem'}}>{error}</p>}
                    <form onSubmit={handleSubmit}>
                        {isSignup && (
                            <div className="auth__form-container_fields-content_input">
                                <label htmlFor="fullName">Full Name</label>
                                <input 
                                    name="fullName" 
                                    type="text"
                                    placeholder="Full Name"
                                    onChange={handleChange}
                                    required
                                />
                            </div>
                        )}
                        <div className="auth__form-container_fields-content_input">
                            <label htmlFor="username">Username</label>
                                <input 
                                    name="username" 
                                    type="text"
                                    placeholder="Username"
                                    onChange={handleChange}
                                    required
                                />
                            </div>
                        {isSignup && (
                            <div className="auth__form-container_fields-content_input">
                                <label htmlFor="phoneNumber">Phone Number</label>
                                <input 
                                    name="phoneNumber" 
                                    type="text"
                                    placeholder="Phone Number"
                                    onChange={handleChange}
                                    required
                                />
                            </div>
                        )}
                        {isSignup && (
                            <div className="auth__form-container_fields-content_input">
                                <label htmlFor="avatarURL">Avatar URL</label>
                                <input 
                                    name="avatarURL" 
                                    type="text"
                                    placeholder="Avatar URL"
                                    onChange={handleChange}
                                    required
                                />
                            </div>
                        )}
                        <div className="auth__form-container_fields-content_input">
                                <label htmlFor="password">Password</label>
                                <input 
                                    name="password" 
                                    type="password"
                                    placeholder="Password"
                                    onChange={handleChange}
                                    required
                                />
                            </div>
                        {isSignup && (
                            <div className="auth__form-container_fields-content_input">
                                <label htmlFor="confirmPassword">Confirm Password</label>
                                <input 
                                    name="confirmPassword" 
                                    type="password"
                                    placeholder="Confirm Password"
                                    onChange={handleChange}
                                    required
                                />
                            </div>
                            )}
                        <div className="auth__form-container_fields-content_button">
                            <button>{isSignup ? "Sign Up" : "Sign In"}</button>
                        </div>
                    </form>
                    <div className="auth__form-container_fields-account">
                        <p>
                            {isSignup
                             ? "Already have an account?" 
                             : "Don't have an account?"
                             }
                             <span onClick={switchMode}>
                             {isSignup ? 'Sign In' : 'Sign Up'}
                             </span>
                        </p>
                    </div>
                </div> 
            </div>
            <div className="auth__form-container_image">
                <img src={signinImage} alt="sign in" />
            </div>
        </div>
    )
}

export default Auth

关键改动说明

  1. try/catch错误捕获:将Axios请求逻辑包裹在try块中,catch块捕获请求异常,避免页面因未处理的错误崩溃。
  2. 错误状态管理:新增error状态变量,在页面显示用户友好的错误提示,同时在输入、切换模式时自动清空提示。
  3. 前端预校验:注册阶段先校验密码与确认密码是否一致,减少无效的后端请求。
  4. 调试日志输出:在catch块中打印完整错误对象(含响应数据、状态码等),快速定位问题根源(如URL错误、参数不符、后端报错)。

调试建议

  • 打开浏览器开发者工具的Console面板,查看catch块打印的请求错误详情,明确错误类型(网络问题、后端业务错误等)。
  • 确认后端服务是否正常运行,URL端口、路径是否与后端接口匹配。
  • 检查请求参数的字段名、格式是否符合后端接口要求。
  • 本地开发若遇跨域问题,需在后端配置CORS规则,或在React项目中配置代理。

内容的提问来源于stack exchange,提问作者Rick Derick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 10:40:58