Thanks for your patience. I'm implementing Firebase on my site but when I call the signup function in FormUp.js (declared in AuthContext.js) it doesn't refer to the function definition. This causes the function called in FormUp.js, not to call its own function defined in AuthContext.js, but falls into the catch branch ('Failed to create an account'). I don't understand why. Hope someone can help me, thanks!
Error:
TypeError: _firebase__WEBPACK_IMPORTED_MODULE_1__.auth.createUserWithEmailAndPassword is not a function
at signup (bundle.js:4226:56)
at handleSubmit (bundle.js:2575:13)
at HTMLUnknownElement.callCallback (bundle.js:41062:18)
at Object.invokeGuardedCallbackDev (bundle.js:41111:20)
at invokeGuardedCallback (bundle.js:41171:35)
at invokeGuardedCallbackAndCatchFirstError (bundle.js:41186:29)
at executeDispatch (bundle.js:45421:7)
at processDispatchQueueItemsInOrder (bundle.js:45453:11)
at processDispatchQueue (bundle.js:45466:9)
at dispatchEventsForPlugins (bundle.js:45477:7)
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
at Navbar (http://localhost:3000/static/js/bundle.js:3361:76)
at Home
Code:
AuthContext.js
import React, { useContext, useState, useEffect } from "react";
import { auth } from "../firebase";
import { createUserWithEmailAndPassword } from "firebase/auth";
const AuthContext = React.createContext();
export function useAuth() {
return useContext(AuthContext);
}
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState();
const [loading, setLoading] = useState(true);
function signup(email, password) {
return auth.createUserWithEmailAndPassword(email, password);
}
function login(email, password) {
return auth.signInWithEmailAndPassword(email, password);
}
function logout() {
return auth.signOut();
}
function resetPassword(email) {
return auth.sendPasswordResetEmail(email);
}
function updateEmail(email) {
return currentUser.updateEmail(email);
}
function updatePassword(password) {
return currentUser.updatePassword(password);
}
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((user) => {
setCurrentUser(user);
setLoading(false);
});
return unsubscribe;
}, []);
const value = {
currentUser,
login,
signup,
logout,
resetPassword,
updateEmail,
updatePassword,
};
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
);
}
firebase.js
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
const firebaseConfig = {
//Hidden
};
const app = initializeApp(firebaseConfig);
const auth = getAuth();
export { app, auth };
FormUp.js
import React, { useRef, useState } from "react";
import { Link } from "react-router-dom";
import {
FormUser,
Input,
Label,
Subtitle,
TextWrapper,
TopLine,
FormButton,
Credentials,
HomePage,
SignInLink,
SignInText,
RedirectSignIn,
Credential,
} from "./Form.elements";
import { FaAngleLeft } from "react-icons/fa";
import { useAuth } from "../../contexts/AuthContext";
import { Alert } from "bootstrap";
const FormUp = ({
primary,
lightBg,
lightTopLine,
lightTextDesc,
buttonLabel,
description,
topLine,
}) => {
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("Password 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 (
<>
<style>
#import
url('https://fonts.googleapis.com/css2?family=Poppins:wght#100;200;300;400;500;600;700;800;900&display=swap');
</style>
<FormUser lightBg={lightBg} onSubmit={handleSubmit}>
<TextWrapper>
<HomePage href="/">
<FaAngleLeft />
<TopLine lightTopLine={lightTopLine}>{topLine}</TopLine>
</HomePage>
<Subtitle lightTextDesc={lightTextDesc}>{description}</Subtitle>
{error && (
<h5 style={{ color: "red", paddingBottom: "30px" }}>{error}</h5>
)}
<Credentials>
<Credential id="email">
<Label>Email</Label>
<Input
ref={emailRef}
required
type="email"
placeholder="Email..."
></Input>
</Credential>
<Credential id="password">
<Label>Password</Label>
<Input
ref={passwordRef}
required
type="password"
placeholder="Password..."
></Input>
</Credential>
<Credential id="password-confirm">
<Label>Password confirmation</Label>
<Input
ref={passwordConfirmRef}
required
type="password"
placeholder="Password confirmation..."
></Input>
</Credential>
</Credentials>
<FormButton disabled={loading} type="submit" big primary={primary}>
{buttonLabel}
</FormButton>
<RedirectSignIn>
<SignInText>Already have an account?</SignInText>
<SignInLink href="/sign-in">Log in</SignInLink>
</RedirectSignIn>
</TextWrapper>
</FormUser>
</>
);
};
export default FormUp;
Well, the problem here is, as the error message suggest, that auth does not have a property called createUserWithEmailAndPassword. What you are searching for is not part of auth. Your code should be something like
function signup(email, password) {
return createUserWithEmailAndPassword(auth, email, password);
}
instead of
function signup(email, password) {
return auth.createUserWithEmailAndPassword(email, password);
}
Check this (if you are using version 8 of the SDK, then you need to use a different approach)
https://firebase.google.com/docs/auth/web/password-auth#create_a_password-based_account
My suggestion is to add a linter to your project to easily catch these issues. In this case the issue would have been immediately visible since the import of createUserWithEmailAndPassword is not used.
Related
the URL shows that it is login page but everything is white, and when I reload it loads the page.
in the console says that many variables from the previous page are null, it seems like it's still on the previous page. why is this happening?
The previous page and the code:
import React, { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import '../styles/UserProfile.css'
import { useAuth } from '../services/authContext'
export default function UserProfile() {
const { currentUser, logout } = useAuth()
const navigate = useNavigate()
const [errorMessage, setErrorMessage] = useState(null)
async function handleLogout() {
try {
await logout()
navigate("/login")
} catch (error) {
console.log(error)
setErrorMessage('An error ocurred when trying to logout')
}
}
return (
<div className="container profile">
<div className="profile">
<h1>Profile</h1>
{errorMessage && (
<div className="error-container">
<strong>{errorMessage}</strong>
</div>
)}
<div className="row">
<h3>Email</h3>
<p>{currentUser.email}</p>
</div>
<div className="row">
<a>Change email</a>
</div>
<div className="row">
<a>Reset password</a>
</div>
<button onClick={handleLogout}>Logout</button>
</div>
</div>
)
}
and when i click logout this happens:
when i reload it loads normally
useAuth code:
import React, { createContext, useContext, useEffect, useState } from 'react'
import {
createUserWithEmailAndPassword,
onAuthStateChanged,
signInWithEmailAndPassword,
signOut,
} from 'firebase/auth'
import { auth } from '../firebase'
const AuthContext = createContext()
export function useAuth() {
return useContext(AuthContext)
}
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState()
function signUp(email, password) {
return createUserWithEmailAndPassword(auth, email, password)
}
function login(email, password) {
return signInWithEmailAndPassword(auth, email, password)
}
function logout() {
return signOut(auth)
}
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, user => {
setCurrentUser(user)
})
return unsubscribe
}, [])
return (
<AuthContext.Provider
value={{
signUp: signUp,
login: login,
logout: logout,
currentUser: currentUser,
}}
>
{children}
</AuthContext.Provider>
)
}
login code:
import React, { useState } from 'react'
import { useAuth } from '../services/authContext'
import { useNavigate, Link } from 'react-router-dom'
import Header from '../components/Header'
export default function Login() {
const { login } = useAuth()
const navigate = useNavigate()
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [loading, setLoading] = useState(false)
const [errorMessage, setErrorMessage] = useState(null)
async function handleSubmit(element) {
element.preventDefault()
setLoading(true)
if (password.length < 6) {
setErrorMessage('The password need to have at least 6 characters!')
setLoading(false)
return
}
try {
await login(email, password)
navigate('/')
} catch (error) {
setErrorMessage('An error occured when trying to login')
}
setLoading(false)
}
return (
<div className="container">
<Header />
<h2>Login</h2>
{errorMessage && (
<div className="error-container">
<strong>{errorMessage}</strong>
</div>
)}
<form onSubmit={handleSubmit}>
<label>Email</label>
<input
type="email"
value={email}
onChange={e => setEmail(e.target.value)}
/>
<label>Password</label>
<input
type="password"
value={password}
onChange={e => {
setPassword(e.target.value)
}}
/>
<button disabled={loading} className="button-block" type="submit1">
Login
</button>
</form>
<div className="center">
<p>
ForgotPassword ? <Link to="/forgot-password">Reset password</Link>
</p>
<p>
Don't have an account ? <Link to="/signup">Create account</Link>
</p>
</div>
</div>
)
}
i consoled log currentUser and currentUser.email before logout, and it's not null, this happens after logging out.
UserProfile.jsx:32:1 is <p>{currentUser.email}</p>. As far as I can tell it appears the currentUser object is nullified and the UserProfile component is rerendered at least once prior to the navigation action being effected to navigate the user to the "/login" path. The UserProfile component falls over when attempting to access currentUser.email when currentUser is null.
You should place a guard on the UI to only render valid content when currentUser is non-null.
Example:
export default function UserProfile() {
const { currentUser, logout } = useAuth();
const navigate = useNavigate();
const [errorMessage, setErrorMessage] = useState(null);
async function handleLogout() {
try {
await logout();
navigate("/login");
} catch (error) {
console.log(error);
setErrorMessage('An error ocurred when trying to logout');
}
}
if (!currentUser) {
return <div>No Current user. Log in.</div>;
}
return (
<div className="container profile">
<div className="profile">
<h1>Profile</h1>
{errorMessage && (
<div className="error-container">
<strong>{errorMessage}</strong>
</div>
)}
<div className="row">
<h3>Email</h3>
<p>{currentUser.email}</p>
</div>
<div className="row">
<a>Change email</a>
</div>
<div className="row">
<a>Reset password</a>
</div>
<button onClick={handleLogout}>Logout</button>
</div>
</div>
)
}
I am New to React and the I am Using Context For First time, I am learning about Authentication with Firebase so I working on this SignUp Component. It was Working Fine Untill I put the Code between Context.Provider and React is not Rendering anything Inside it
I also tried creating test.jsx which return Text in div to see if my SignUp component is causing error but even test is not rendering
I tried to find other article but i cannot pinpoint issue in my Code
App.js
import React from 'react'
import SignUp from "./components/SignUp";
import {Container} from 'react-bootstrap'
import { AuthProvider } from "./context/AuthContext";
function App() {
return (
<AuthProvider>
<SignUp />
</AuthProvider>
);
}
export default App;
AuthContext.js
import React, { useContext, useEffect, useState } from 'react'
import { auth } from '../firebase'
const AuthContext = React.createContext()
export function useAuth() {
return useContext(AuthContext);
};
export function AuthProvider({ childern }) {
const [currentUser, setCurrentUser] = useState();
function signUp(email, password) {
return auth.createUserWithEmailAndPassword(email, password);
}
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(user => {
setCurrentUser(user);
console.log(user)
});
return unsubscribe
},[])
const value = {
currentUser,
signUp
}
return (
<AuthContext.Provider value={value} >
{childern}
</AuthContext.Provider>
)
};
Btw SignUp is not Rendering at all It is blank page
SignUp.jsx
import React, { useRef, useState } from 'react'
import { Form, Card, Button, Alert } from 'react-bootstrap'
import { useAuth } from '../context/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['Password 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.Control>
</Form.Group>
<Form.Group id="password">
<Form.Label>Password</Form.Label>
<Form.Control type="password" ref={passwordRef} required ></Form.Control>
</Form.Group>
<Form.Group id="password-confrim">
<Form.Label>Password Confrimation</Form.Label>
<Form.Control type="password" ref={passwordConfirmRef} required ></Form.Control>
</Form.Group>
<Button
disbled={loading}
className="w-100 mt-2" 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 Dev Tools In Chrome
App -> AuthProvider -> Context.Provider
AuthProvider
Prop
{
"children": "<ForwardRef />"
}
Hooks
[
{
"name": "State",
"value": null
}
},
{
"name": "Effect",
"value": "ƒ () {}"
}
}
]
Context.Provider
Props
{
"value": {
"currentUser": null,
"signUp": "ƒ signUp() {}"
}
}
i have been trying to find solution but couldn't
thanks for your patience. I'm implementing Firebase on my site but when I call the signup function in FormUp.js (declared in AuthContext.js) it doesn't refer to the function definition. This causes the function called in FormUp.js, not to call its own function defined in AuthContext.js, but falls into the catch branch ('Failed to create an account'). I don't understand why. Hope someone can help me, thanks!
Error:
TypeError: _firebase__WEBPACK_IMPORTED_MODULE_1__.auth.createUserWithEmailAndPassword is not a function
at signup (bundle.js:4226:56)
at handleSubmit (bundle.js:2575:13)
at HTMLUnknownElement.callCallback (bundle.js:41062:18)
at Object.invokeGuardedCallbackDev (bundle.js:41111:20)
at invokeGuardedCallback (bundle.js:41171:35)
at invokeGuardedCallbackAndCatchFirstError (bundle.js:41186:29)
at executeDispatch (bundle.js:45421:7)
at processDispatchQueueItemsInOrder (bundle.js:45453:11)
at processDispatchQueue (bundle.js:45466:9)
at dispatchEventsForPlugins (bundle.js:45477:7)
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
at Navbar (http://localhost:3000/static/js/bundle.js:3361:76)
at Home
Code:
AuthContext.js
import React, { useContext, useState, useEffect } from "react";
import { auth } from "../firebase";
import { createUserWithEmailAndPassword } from "firebase/auth";
const AuthContext = React.createContext();
export function useAuth() {
return useContext(AuthContext);
}
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState();
const [loading, setLoading] = useState(true);
function signup(email, password) {
return auth.createUserWithEmailAndPassword(email, password);
}
function login(email, password) {
return auth.signInWithEmailAndPassword(email, password);
}
function logout() {
return auth.signOut();
}
function resetPassword(email) {
return auth.sendPasswordResetEmail(email);
}
function updateEmail(email) {
return currentUser.updateEmail(email);
}
function updatePassword(password) {
return currentUser.updatePassword(password);
}
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((user) => {
setCurrentUser(user);
setLoading(false);
});
return unsubscribe;
}, []);
const value = {
currentUser,
login,
signup,
logout,
resetPassword,
updateEmail,
updatePassword,
};
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
);
}
firebase.js
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
const firebaseConfig = {
//Hidden
};
const app = initializeApp(firebaseConfig);
const auth = getAuth();
export { app, auth };
FormUp.js
import React, { useRef, useState } from "react";
import { Link } from "react-router-dom";
import {
FormUser,
Input,
Label,
Subtitle,
TextWrapper,
TopLine,
FormButton,
Credentials,
HomePage,
SignInLink,
SignInText,
RedirectSignIn,
Credential,
} from "./Form.elements";
import { FaAngleLeft } from "react-icons/fa";
import { useAuth } from "../../contexts/AuthContext";
import { Alert } from "bootstrap";
const FormUp = ({
primary,
lightBg,
lightTopLine,
lightTextDesc,
buttonLabel,
description,
topLine,
}) => {
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("Password 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 (
<>
<style>
#import
url('https://fonts.googleapis.com/css2?family=Poppins:wght#100;200;300;400;500;600;700;800;900&display=swap');
</style>
<FormUser lightBg={lightBg} onSubmit={handleSubmit}>
<TextWrapper>
<HomePage href="/">
<FaAngleLeft />
<TopLine lightTopLine={lightTopLine}>{topLine}</TopLine>
</HomePage>
<Subtitle lightTextDesc={lightTextDesc}>{description}</Subtitle>
{error && (
<h5 style={{ color: "red", paddingBottom: "30px" }}>{error}</h5>
)}
<Credentials>
<Credential id="email">
<Label>Email</Label>
<Input
ref={emailRef}
required
type="email"
placeholder="Email..."
></Input>
</Credential>
<Credential id="password">
<Label>Password</Label>
<Input
ref={passwordRef}
required
type="password"
placeholder="Password..."
></Input>
</Credential>
<Credential id="password-confirm">
<Label>Password confirmation</Label>
<Input
ref={passwordConfirmRef}
required
type="password"
placeholder="Password confirmation..."
></Input>
</Credential>
</Credentials>
<FormButton disabled={loading} type="submit" big primary={primary}>
{buttonLabel}
</FormButton>
<RedirectSignIn>
<SignInText>Already have an account?</SignInText>
<SignInLink href="/sign-in">Log in</SignInLink>
</RedirectSignIn>
</TextWrapper>
</FormUser>
</>
);
};
export default FormUp;
I have tried to create password reset option to web app with firebase and Other firebase options are works fine like GoogleLogin and Email Sign Up, but when i try sendPasswordResetEmail it returns following error,
TypeError: firebase__WEBPACK_IMPORTED_MODULE_1_.auth.sendPasswordResetEmail is not a function
Here's the Code,
firebase.js
import { initializeApp } from "firebase/app";
import { getAuth, GoogleAuthProvider, signInWithPopup } from "firebase/auth";
const firebaseConfig = {
apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.REACT_APP_FIREBASE_APP_ID
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
export const provider = new GoogleAuthProvider();
export const signInWithGooglePopUp = signInWithPopup
export default app;
AuthContext.js
import React, { useContext, useState, useEffect } from "react"
import { auth, provider, signInWithGooglePopUp } from "../firebase"
const AuthContext = React.createContext()
export function useAuth() {
return useContext(AuthContext)
}
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState()
const [loading, setLoading] = useState(true)
function signup(email, password) {
return auth.createUserWithEmailAndPassword(email, password)
}
function login(email, password) {
return auth.signInWithEmailAndPassword(email, password)
}
function logout() {
return auth.signOut()
}
function resetPassword(email) {
alert('')
return auth.sendPasswordResetEmail(email).then((a) => {
alert(a)
})
}
function updateEmail(email) {
return currentUser.updateEmail(email)
}
function updatePassword(password) {
return currentUser.updatePassword(password)
}
function signupWithGoogle() {
return signInWithGooglePopUp(auth, provider).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error)
})
}
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(user => {
setCurrentUser(user)
setLoading(false)
})
return unsubscribe
}, [])
const value = {
currentUser,
login,
signup,
logout,
resetPassword,
updateEmail,
updatePassword,
signupWithGoogle
}
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
)
}
ForgotPassword.js
import React, { useRef, useState } from "react"
import { Form, Button, Card, Alert } from "react-bootstrap"
import { useAuth } from "../contexts/AuthContext"
import { Link } from "react-router-dom"
export default function ForgotPassword() {
const emailRef = useRef()
const { resetPassword } = useAuth()
const [error, setError] = useState("")
const [message, setMessage] = useState("")
const [loading, setLoading] = useState(false)
async function handleSubmit(e) {
e.preventDefault()
try {
setMessage("")
setError("")
setLoading(true)
console.log('wait')
await resetPassword(emailRef.current.value)
console.log('done')
setMessage("Check your inbox for further instructions")
} catch (error) {
console.log(error)
setError("Failed to reset password")
}
setLoading(false)
}
return (
<>
<Card>
<Card.Body>
<h2 className="text-center mb-4">Password Reset</h2>
{error && <Alert variant="danger">{error}</Alert>}
{message && <Alert variant="success">{message}</Alert>}
<Form onSubmit={handleSubmit}>
<Form.Group id="email">
<Form.Label>Email</Form.Label>
<Form.Control type="email" ref={emailRef} required />
</Form.Group>
<Button disabled={loading} className="w-100" type="submit">
Reset Password
</Button>
</Form>
<div className="w-100 text-center mt-3">
<Link to="/login">Login</Link>
</div>
</Card.Body>
</Card>
<div className="w-100 text-center mt-2">
Need an account? <Link to="/signup">Sign Up</Link>
</div>
</>
)
}
What's wrong here, Thanks in Advance.
You are using Firebase Modular SDK (V9.0.0+) where sendPasswordResetEmail is a function and not a method on Auth instance. So that should be:
import { sendPasswordResetEmail } from "firebase/auth"
import { auth } from "../firebase"
function resetPassword(email) {
return sendPasswordResetEmail(auth, email).then((a) => {
alert("Password reset email sent")
})
}
The same applies for others functions like createUserWithEmailAndPassword(), signOut(), etc. I'm not sure why the error shows up for this one only.
Do checkout the documentation of Firebase Auth to learn more about these functions.
I have been trying to solve this issue wherein, I can grab the accessToken after login only? I have been stuck on this
The main problem is, the Token is already looking for it on localstorage, but I'm not even logged in yet. How can I make the user to login first before looking to the local storage
requestMethod.js
import axios from 'axios'
const BASE_URL = 'http://localhost:5000/api'
const TOKEN = JSON.parse(JSON.parse(localStorage.getItem('persist:root')).user)
.currentUser.accessToken
export const publicRequest = axios.create({
baseURL: BASE_URL,
})
export const userRequest = axios.create({
baseURL: BASE_URL,
headers: { token: `Bearer ${TOKEN}` },
})
Login.jsx
import { useEffect } from "react"
import { useState } from "react"
import { useDispatch } from "react-redux"
import { useHistory } from "react-router"
import { login } from "../../redux/apiCalls"
import { userRequest } from "../../requestMethod"
const Login = () => {
let history = useHistory()
const [username, setUsername] = useState("")
const [password, setPassword] = useState("")
const dispatch = useDispatch()
const handleClick = (e) =>{
e.preventDefault()
login(dispatch,{username,password})
history.push('/home')
}
useEffect(() =>{
try {
} catch (error) {
}
},[])
return (
<div style={{display: 'flex', alignItems:"center", justifyContent:"center", height: '100vh', flexDirection: "column"}}>
<form action="">
<input style={{padding: 10, marginBottom:20}} value={username} type="text" placeholder="username" onChange={e => setUsername(e.target.value)} />
<input style={{padding: 10, marginBottom:20}} value={password} type="password" placeholder="password" onChange={e => setPassword(e.target.value)} />
<button style={{padding: 10, width: 100}} onClick={handleClick}>Login</button>
</form>
</div>
)
}
export default Login
apicalls.js
import { loginFailure, loginStart, loginSuccess } from './userRedux'
export const login = async (dispatch, user) => {
dispatch(loginStart())
try {
const res = await publicRequest.post('/auth/login', user)
const TOKEN = JSON.parse(
JSON.parse(localStorage.getItem('persist:root')).user
).currentUser.accessToken
dispatch(loginSuccess(res.data))
} catch (error) {
dispatch(loginFailure())
}
}
You have to lookup on localstorage first.
Just check if localstorage contains token or not. If not, render some message and redirect user to login page.
Use optional chaining(?.):
const TOKEN = JSON.parse(JSON.parse(localStorage.getItem('persist:root'))?.user)
?.currentUser?.accessToken;