React Web认证中setError无法显示错误信息的问题求助
问题:React认证应用提交不匹配密码时无错误提示
我跟着Web Dev Simplified的YouTube教程(约20分钟处)开发React Web认证应用,遇到一个异常:提交邮箱与不匹配的密码时,本应显示错误信息,但无法触发任何错误提示。尝试过初始化错误信息可正常显示,但后续调用setError无法更新错误内容,核对过命名一致性,已排查多日未解决。
相关代码如下:
./index.js
import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './components/App'; import 'bootstrap/dist/css/bootstrap.min.css'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <App /> </React.StrictMode> );
./components/App.js
import React from "react"; import Signup from './Signup' import { Container } from 'react-bootstrap' import { AuthProvider } from '../contexts/AuthContext' function App() { return ( <AuthProvider> <Container className="d-flex align-items-center justify-content-center" style={{ minHeight: "100vh" }}> <div className="w-100" style={{ maxWidth: "400px" }}> <Signup /> </div> </Container> </AuthProvider> ) } export default App;
./contexts/AuthContext.js
import React, { useContext, useState, useEffect } from 'react' import { auth } from '../firebase' const AuthContext = React.createContext() export function useAuth() { return useContext(AuthContext) } export function AuthProvider({ children }) { const [currentUser, setCurrentUser] = useState() function signup(email, password) { return auth.createUserWithEmailAndPassword(email, password) } useEffect(() => { const unsubscribe = auth.onAuthStateChanged(user => { setCurrentUser(user) }) return unsubscribe }, []) const value = { currentUser, signup } return <AuthContext.Provider value={value}>{children}</AuthContext.Provider> }
./components/Signup.js
import React, { useRef, useState } from 'react'; import { Form, Button, Card, Alert } from 'react-bootstrap'; import { useAuth } from '../contexts/AuthContext'; export default function Signup() { const emailRef = useRef(); const passwordRef = useRef(); const passwordConfirmRef = useRef(); const { signup } = useAuth(); const [error, setError] = useState(""); const [loading, setLoading] = useState(false); async function handleSubmit(e) { e.preventDefault(); if (passwordRef.current.value !== passwordConfirmRef.current.value) { return setError("Passwords do not match"); } try { setError(""); setLoading(true); await signup(emailRef.current.value, passwordRef.current.value); } catch { setError("Failed to create an account"); } setLoading(false); } return ( <> <Card> <Card.Body> <h2 className="text-center mb-4">Sign Up</h2> {error && <Alert variant="danger">{error}</Alert>} <Form onSubmit={handleSubmit}> <Form.Group id="email"> <Form.Label>Email</Form.Label> <Form.Control type="email" ref={emailRef} required /> </Form.Group> <Form.Group id="password"> <Form.Label>Password</Form.Label> <Form.Control type="password" ref={passwordRef} required /> </Form.Group> <Form.Group id="password-confirm"> <Form.Label>Password Confirmation</Form.Label> <Form.Control type="password" ref={passwordConfirmRef} required /> </Form.Group> </Form> <Button disabled={loading} className="w-100" type="submit"> Sign Up </Button> </Card.Body> </Card> <div className="w-100 text-center mt-2"> Already have an account? Log In </div> </> ); }
解决方案
核心问题是提交按钮不在<Form>标签内部,导致表单的onSubmit事件未被触发,handleSubmit函数完全没执行,自然不会运行密码匹配检测、错误状态更新的逻辑。
修改./components/Signup.js,将<Button>移动到<Form>标签内部:
// 修改后的Signup.js返回部分 return ( <> <Card> <Card.Body> <h2 className="text-center mb-4">Sign Up</h2> {error && <Alert variant="danger">{error}</Alert>} <Form onSubmit={handleSubmit}> <Form.Group id="email"> <Form.Label>Email</Form.Label> <Form.Control type="email" ref={emailRef} required /> </Form.Group> <Form.Group id="password"> <Form.Label>Password</Form.Label> <Form.Control type="password" ref={passwordRef} required /> </Form.Group> <Form.Group id="password-confirm"> <Form.Label>Password Confirmation</Form.Label> <Form.Control type="password" ref={passwordConfirmRef} required /> </Form.Group> {/* 将按钮移入Form内部 */} <Button disabled={loading} className="w-100 mt-3" type="submit"> Sign Up </Button> </Form> </Card.Body> </Card> <div className="w-100 text-center mt-2"> Already have an account? Log In </div> </> );
原因说明
React Bootstrap的<Form>组件遵循HTML表单的常规逻辑:只有当提交按钮处于表单标签内部时,点击按钮才会触发表单的onSubmit事件,进而绑定的handleSubmit函数才会执行。之前按钮在Form外部,点击时只是普通按钮,不会触发表单提交逻辑,所以所有错误检测和状态更新的代码都没运行。
内容的提问来源于stack exchange,提问作者Spailll
相关产品推荐
相关产品推荐

