Home > Blockchain >  React web authentication issue with setError and error
React web authentication issue with setError and error

Time:12-26

I'm making a web authentication app in react based on a YouTube video from Web Dev Simplified (approx 20 min in)and have been running into an odd issue.

I saw someone post a similar question at the same point in development but I don't believe I have the same issue. I'm not getting any errors, the only issue I am having is on the error messages showing. When I submit an email and pair of mismatched passwords it should give me an error message, but I cannot get it to display any errors. This is the code:

./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>
        </>
    );
}

I've tried changing the [error, setError] assignment to const [error, setError] = useState(""); and it displayed the initially assigned error properly, but it still refuses to assign any subsequent messages. I've also tried to make sure all the names are correct, and uniform. I have been troubleshooting this for a couple days now to little success. JavaScript is not my main language, and I'm still learning it so I'm sure I'm just missing something simple. Thanks for the help!

CodePudding user response:

I found the issue. I had placed the button outside of the card which caused it to not activate what it was supposed to. Moving the Button tag inside the Card tag fixed everything.

  • Related