Why does localStorage.Remove not work? React - reactjs

import { Navigate, useLocation } from 'react-router-dom';
export function RequireAuth({ children }) {
const token = localStorage.getItem('token');
const location = useLocation();
if (!token) {
return <Navigate to='/' state={{ from: location }} replace />;
}
return children;
}
export default RequireAuth;
import MotionLeftSideSignin from '../components/MotionSignIn/motionsigninleftside.js';
import SignUpBar from '../components/MotionSignIn/SignupBar.js';
import { MainContainer,SignInContainer,RightContainer,Header,Inputboxes,UsernameInput,PasswordnameInput,SigninbuttonBox,SigninButton} from '../style/signinStyle.js';
import { useState } from 'react';
import {useNavigate} from 'react-router-dom';
const Signin = () => {
const [email,setEmail] = useState();
const [password,setPassword] = useState();
const navigate= useNavigate();
const updateEmail = (event) =>{
setEmail(event.target.value);
}
const updatePassword = (event) =>{
setPassword(event.target.value);
}
const login = (event) =>{
event.preventDefault();
const url = "https://motion.propulsion-home.ch/backend/api/auth/token/"
const data = {
email:email,
password:password,
};
const fetchConfig = {
method:"POST",
headers: new Headers({
"Content-Type": "application/json",
}),
body: JSON.stringify(data),
};
fetch(url,fetchConfig)
.then((response) => {
return response.json();
})
.then((data) => {
if(data.access === undefined) {
alert("Please try again")
}else{
localStorage.setItem('token',data.access);
navigate("/Posts")
};
});
const NavigationBar = () => {
const navigate = useNavigate();
const toFriendsPage = () => {
navigate("/FindFriends");
}
const toSignInPage = () =>{
navigate("/");
}
const toPostsPage = () =>{
navigate("/Posts");
}
const togglePopUp = () => {
const popUp = document.querySelector(".popup")
const popUpDisplay = window.getComputedStyle( popUp, null ).display
if (popUpDisplay === "flex") {
popUp.style.display = "none"
} else {
popUp.style.display = "flex"
}
}
const logOut = () => {
localStorage.removeItem('token');
}
return (
<ProfilOverlayHeader>
<NavigationBarLogoDiv>
<NavigationBarLogo src={logo} alt="logo"/>
<NavigationBarTitle onClick={toSignInPage}>Motion</NavigationBarTitle>
</NavigationBarLogoDiv>
<Post_FriendsDiv>
<Post_FriendsDivPosts>
<Post_FriendsDivPostsImg src={postsImg} alt="posts"/>
<Clickables onClick={toPostsPage}>Posts</Clickables>
</Post_FriendsDivPosts>
<Post_FriendsDivFriendsImg src={friendsImg} alt="friends"/>
<Clickables onClick={toFriendsPage}>Find Friends</Clickables>
</Post_FriendsDiv>
<Notif_ProfilPic_SettingsDiv>
<NotificationBell src={notificationBellImg} alt="your notifications"/>
<NavigationBarProfilPic onClick={ togglePopUp } src={profilPic} alt="your profil picture"/>
<ProfilPopUpDiv className="popup">
<TopDiv>
<ProfileIcon src={ ProfilePopUpIcon } alt="profile icon"/>
<p>Profile</p>
</TopDiv>
<BottomDiv>
<LogOutIcon src={ LogoutIcon } alt="profile icon"/>
<LogOutButton onclick={logOut}>Logout</LogOutButton>
import './App.css';
import SignIn from './pages/signin.js';
import SignUpStep1 from './pages/signup-step1.js'
import {Route,Routes} from 'react-router-dom';
import SignUpStep2 from './pages/signup-step2.js'
import Verification from './pages/verification.js'
import Posts from './pages/posts-pages/PostsPage.js'
import FindFriends from './pages/find-friends-pages/FindFriendsPage.js'
import RequireAuth from './components/Auth/RequireAuth.js'
import ProfilOverlay3_1 from "./pages/ProfilOverlay3_1";
import ProfilOverlay3_2 from "./pages/ProfilOverlay3_2";
import ProfilOverlay3_3 from "./pages/ProfilOverlay3_3";
import ProfilOverlay3_4 from './pages/ProfilOverlay3_4';
function App() {
return (
<Routes>
<Route path="/" element={<SignIn/>} />
<Route path="/SignUpStep1" element={<SignUpStep1/>} />
<Route path="/SignUpStep2" element={<SignUpStep2/>} />
<Route path="/Verification" element={<Verification/>} />
<Route path="/Posts" element={<RequireAuth><Posts/></RequireAuth>} />
<Route path= "/FindFriends" element={<RequireAuth><FindFriends/></RequireAuth>} />
<Route path="/ProfilPosts" element={<RequireAuth><ProfilOverlay3_1/></RequireAuth>}/>
<Route path="/ProfilEdit" element={ <RequireAuth><ProfilOverlay3_2/></RequireAuth> } />
<Route path="/UserPosts" element= { <RequireAuth><ProfilOverlay3_3/> </RequireAuth>} />
<Route path="/UserFriends" element= {<RequireAuth><ProfilOverlay3_4 /> </RequireAuth>} />
</Routes>
// <FindFriendsNotification />
)
}
export default App;
Hi I have added an authentication using a JSON Web Token for a react project i'm working on from a bootcamp (so i am very new to this). The authentication works for registration , login and browser refresh. But when I call the logOut function on the onClick logout button it doesn't log me out. I have console logged localStorage.getItem('token') before and after the logout function. The first console log is present and the second not, so I guess it has removed the token but then it doesn't redirect me to the signin page. Also if i refresh it stays on the same page. Does anyone know why this is happening? thanks

The way you defined variable token makes it static:
const token = localStorage.getItem('token');
You only run this once at the start of routes using RequireAuth, and I'm guessing it doesn't run after you update your local storage, therefore even though you removed the token, the component never updates.
I personally would use the React Context API to handle issues like this. But for the sake of just implementing the function, you can always hard-code a navigate('/') function after logging out.

Related

Is it normal to see other pages while refreshing the page? [duplicate]

I am having some issues with my routing currently when authenticated. Whenever I try to access my ViewPortfolio page at localhost:3000/portfolio/portfolioId it will redirect me back to my homepage. I am not sure what is going on. I have also tried manipulating the URL by modifying it to the correct URL link but it also redirects me back to /homepage when I am authenticated. The source codes can be found below. App.js is my router with PrivateRoute as the private route component and finally, CreateInterview.js where I redirect using js windows.location function to ViewPortfolio.js which will use useParams() react hook to get the param. But instead now after creating successfully and redirect to the correct URL with the portfolioId it will redirect back to homepage within less than a second.
PrivateRoute.js
import React from 'react'
import { Route, Redirect } from 'react-router-dom'
import { useAuth } from '../contexts/AuthContext'
const PrivateRoute = ({ component: Component, ...rest }) => {
const { currentUser } = useAuth()
return (
<Route
{...rest}
render={(props) => {
if (currentUser) {
return <Component {...props} />
} else {
return <Redirect to={{
pathname: "/",
state:{
from: props.location
}
}}/>
}
}
}>
</Route>
)
}
export default PrivateRoute
App.js
import React from "react"
.
.
.
import PublicRoute from "./PublicRoute";
function App() {
return (
<AuthProvider>
<Router>
<Switch>
{/* Auth Routes */}
<PublicRoute exact path='/' component={Login} />
.
.
.
<PrivateRoute exact path='/createInterview' component={CreateInterview} />
<PrivateRoute path='/manageInterview' component={ManageInterview} />
<PrivateRoute path='/portfolio/:portfolioId' component={ViewPortfolio} />
{/* Non-Existance Routes */}
<Route path="*" component={() => "404 NOT FOUND"} />
</Switch>
</Router>
</AuthProvider>
)
}
export default App
CreatInterview.js redirecting in js (onSubmit of the form)
async function handleSubmit(e) {
e.preventDefault();
setError('');
setLoading(true);
await database.portfolioRef.add({
intervieweeName: intervieweeNameRef.current.value,
intervieweeEmail: intervieweeEmailRef.current.value,
intervieweeMobileNumber: intervieweeMobileRef.current.value,
projectTitle: projectTitleRef.current.value,
portfolioTitle: portfolioNameRef.current.value,
dateCreated: new Date().toLocaleString('en-SG'),
createdBy: currentUser.displayName
}).then(function(docRef) {
console.log("This is the Document ID " + docRef.id.toString());
console.log(docRef.id);
window.location = '/portfolio/' + docRef.id;
})
setLoading(false)
}
Part of ViewPortfolio.js to receive the portfolioId from CreateInterview.js
const ViewPortfolio = () => {
let { portfolioId } = useParams();
AuthContext.js
import React, { useContext, useState, useEffect } from "react"
import { auth, database } from "../firebase";
import { getDocs, query, where } from "firebase/firestore";
const AuthContext = React.createContext()
export function useAuth() {
return useContext(AuthContext)
}
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState(null)
const [loading, setLoading] = useState(true)
function login(email, password) {
return auth.signInWithEmailAndPassword(email, password).then(() => {
const Doc = query(database.usersRef, where("email", "==", email));
getDocs(Doc).then((querySnapshot) => {
let values = '';
querySnapshot.forEach((doc) => {
values = doc.id;
});
var userUpdate = database.usersRef.doc(values);
userUpdate.update({
lastActive: new Date().toLocaleString('en-SG'),
})
})
});
}
function logout() {
return auth.signOut();
}
function forgetPassword(email) {
return auth.sendPasswordResetEmail(email);
}
function updateEmail(email) {
return currentUser.updateEmail(email)
}
function updatePassword(password) {
return currentUser.updatePassword(password)
}
function updateDisplayName(name) {
return currentUser.updateDisplayName(name)
}
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged( user => {
setLoading(false)
setCurrentUser(user)
})
return unsubscribe
}, [])
const value = {
currentUser,
login,
forgetPassword,
logout,
updateEmail,
updatePassword,
updateDisplayName,
}
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
)
}
The initial currentUser state matches the unauthenticated state, so when the app initially renders, if you are accessing a protected route the redirection will occur because the currentUser state hasn't updated yet.
Since onAuthStateChanged returns null for unauthenticated users then I suggest using anything other than null for the initial currentUser state. undefined is a good indeterminant value. You can use this indeterminant value to conditionally render a loading indicator, or nothing at all, while the auth status is confirmed on the initial render.
AuthProvider
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState(); // <-- undefined
...
PrivateRoute
const PrivateRoute = (props) => {
const { currentUser } = useAuth();
if (currentUser === undefined) {
return null; // or loading spinner, etc...
}
return currentUser
? (
<Route {...props} />
)
: (
<Redirect
to={{
pathname: "/",
state: {
from: props.location
}
}}
/>
);
}
You should also really replace the window.location = '/portfolio/' + docRef.id; logic with a history.push('/portfolio/' + docRef.id); so you are not unnecessarily reloading the page.
const history = useHistory();
...
async function handleSubmit(e) {
e.preventDefault();
setError('');
setLoading(true);
try {
const docRef = await database.portfolioRef.add({
intervieweeName: intervieweeNameRef.current.value,
intervieweeEmail: intervieweeEmailRef.current.value,
intervieweeMobileNumber: intervieweeMobileRef.current.value,
projectTitle: projectTitleRef.current.value,
portfolioTitle: portfolioNameRef.current.value,
dateCreated: new Date().toLocaleString('en-SG'),
createdBy: currentUser.displayName
});
history.push('/portfolio/' + docRef.id);
} catch (error) {
// handle error, clear loading state
setLoading(false);
}
}

Login with Firebase and React Router Dom (How to use onAuthStateChanged) [duplicate]

I am having some issues with my routing currently when authenticated. Whenever I try to access my ViewPortfolio page at localhost:3000/portfolio/portfolioId it will redirect me back to my homepage. I am not sure what is going on. I have also tried manipulating the URL by modifying it to the correct URL link but it also redirects me back to /homepage when I am authenticated. The source codes can be found below. App.js is my router with PrivateRoute as the private route component and finally, CreateInterview.js where I redirect using js windows.location function to ViewPortfolio.js which will use useParams() react hook to get the param. But instead now after creating successfully and redirect to the correct URL with the portfolioId it will redirect back to homepage within less than a second.
PrivateRoute.js
import React from 'react'
import { Route, Redirect } from 'react-router-dom'
import { useAuth } from '../contexts/AuthContext'
const PrivateRoute = ({ component: Component, ...rest }) => {
const { currentUser } = useAuth()
return (
<Route
{...rest}
render={(props) => {
if (currentUser) {
return <Component {...props} />
} else {
return <Redirect to={{
pathname: "/",
state:{
from: props.location
}
}}/>
}
}
}>
</Route>
)
}
export default PrivateRoute
App.js
import React from "react"
.
.
.
import PublicRoute from "./PublicRoute";
function App() {
return (
<AuthProvider>
<Router>
<Switch>
{/* Auth Routes */}
<PublicRoute exact path='/' component={Login} />
.
.
.
<PrivateRoute exact path='/createInterview' component={CreateInterview} />
<PrivateRoute path='/manageInterview' component={ManageInterview} />
<PrivateRoute path='/portfolio/:portfolioId' component={ViewPortfolio} />
{/* Non-Existance Routes */}
<Route path="*" component={() => "404 NOT FOUND"} />
</Switch>
</Router>
</AuthProvider>
)
}
export default App
CreatInterview.js redirecting in js (onSubmit of the form)
async function handleSubmit(e) {
e.preventDefault();
setError('');
setLoading(true);
await database.portfolioRef.add({
intervieweeName: intervieweeNameRef.current.value,
intervieweeEmail: intervieweeEmailRef.current.value,
intervieweeMobileNumber: intervieweeMobileRef.current.value,
projectTitle: projectTitleRef.current.value,
portfolioTitle: portfolioNameRef.current.value,
dateCreated: new Date().toLocaleString('en-SG'),
createdBy: currentUser.displayName
}).then(function(docRef) {
console.log("This is the Document ID " + docRef.id.toString());
console.log(docRef.id);
window.location = '/portfolio/' + docRef.id;
})
setLoading(false)
}
Part of ViewPortfolio.js to receive the portfolioId from CreateInterview.js
const ViewPortfolio = () => {
let { portfolioId } = useParams();
AuthContext.js
import React, { useContext, useState, useEffect } from "react"
import { auth, database } from "../firebase";
import { getDocs, query, where } from "firebase/firestore";
const AuthContext = React.createContext()
export function useAuth() {
return useContext(AuthContext)
}
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState(null)
const [loading, setLoading] = useState(true)
function login(email, password) {
return auth.signInWithEmailAndPassword(email, password).then(() => {
const Doc = query(database.usersRef, where("email", "==", email));
getDocs(Doc).then((querySnapshot) => {
let values = '';
querySnapshot.forEach((doc) => {
values = doc.id;
});
var userUpdate = database.usersRef.doc(values);
userUpdate.update({
lastActive: new Date().toLocaleString('en-SG'),
})
})
});
}
function logout() {
return auth.signOut();
}
function forgetPassword(email) {
return auth.sendPasswordResetEmail(email);
}
function updateEmail(email) {
return currentUser.updateEmail(email)
}
function updatePassword(password) {
return currentUser.updatePassword(password)
}
function updateDisplayName(name) {
return currentUser.updateDisplayName(name)
}
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged( user => {
setLoading(false)
setCurrentUser(user)
})
return unsubscribe
}, [])
const value = {
currentUser,
login,
forgetPassword,
logout,
updateEmail,
updatePassword,
updateDisplayName,
}
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
)
}
The initial currentUser state matches the unauthenticated state, so when the app initially renders, if you are accessing a protected route the redirection will occur because the currentUser state hasn't updated yet.
Since onAuthStateChanged returns null for unauthenticated users then I suggest using anything other than null for the initial currentUser state. undefined is a good indeterminant value. You can use this indeterminant value to conditionally render a loading indicator, or nothing at all, while the auth status is confirmed on the initial render.
AuthProvider
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState(); // <-- undefined
...
PrivateRoute
const PrivateRoute = (props) => {
const { currentUser } = useAuth();
if (currentUser === undefined) {
return null; // or loading spinner, etc...
}
return currentUser
? (
<Route {...props} />
)
: (
<Redirect
to={{
pathname: "/",
state: {
from: props.location
}
}}
/>
);
}
You should also really replace the window.location = '/portfolio/' + docRef.id; logic with a history.push('/portfolio/' + docRef.id); so you are not unnecessarily reloading the page.
const history = useHistory();
...
async function handleSubmit(e) {
e.preventDefault();
setError('');
setLoading(true);
try {
const docRef = await database.portfolioRef.add({
intervieweeName: intervieweeNameRef.current.value,
intervieweeEmail: intervieweeEmailRef.current.value,
intervieweeMobileNumber: intervieweeMobileRef.current.value,
projectTitle: projectTitleRef.current.value,
portfolioTitle: portfolioNameRef.current.value,
dateCreated: new Date().toLocaleString('en-SG'),
createdBy: currentUser.displayName
});
history.push('/portfolio/' + docRef.id);
} catch (error) {
// handle error, clear loading state
setLoading(false);
}
}

Reactjs redirect to dashboard page after successful login with react-router-dom (v6)

I'm working simple reactjs login form with redux/toolkit. I wanted to redirect to dashboard page after successful login. It's throwing following error. I'm new to reactjs and please let me know if I missed anything.
Error:
Uncaught (in promise) Error: Invalid hook call. Hooks can only be called inside of the body of a function component.
authSlice.js
import { useNavigate } from 'react-router-dom';
export const submitLogin =
({
email,
password
}) =>
async dispatch => {
const history = useNavigate();
return jwtService
.signInWithEmailAndPassword(email, password)
.then(user => {
history('/dashboard');
return dispatch(loginSuccess());
})
.catch(error => {
return dispatch(loginError(error));
});
};
const authSlice = createSlice({
name: 'auth',
initialState,
reducers: {
loginSuccess: ....
loginError: ....
logoutSuccess: ....
},
extraReducers: {},
});
export const { loginSuccess, loginError, logoutSuccess } = authSlice.actions;
export default authSlice.reducer;
Login.js
const Login = () => {
function handleSubmit(model) {
dispatch(submitLogin(model));
}
return (
<Formsy onValidSubmit={handleSubmit} ref={formRef}>
<input type="text" placeholder="username" />
....
</Formsy>
)
}
App.js
<Routes>
<Route path="/dashboard" element={<ProtectedRoutes />}>
<Route path="" element={<Dashboard />} />
</Route>
<Route exact path="/" element={<Login />} />
<Route path="*" element={<PageNotFound />} />
</Routes>
import React from 'react';
import { useSelector } from 'react-redux';
import { Navigate, Outlet } from 'react-router-dom';
const useAuth = () => {
const auth = useSelector(({ auth }) => auth);
return auth && auth.loggedIn;
};
const ProtectedRoutes = () => {
const isAuth = useAuth();
return isAuth ? <Outlet /> : <Navigate to="/" />
}
export default ProtectedRoutes;
Issue
You are attempting to use the useNavigate hook outside a React component, which is an invalid use. React hooks must be called at the top-level, they cannot be called conditionally, in functions, loops, etc...
Rules of hooks
Solutions
Pass the navigate function to the submitLogin action creator.
export const submitLogin = ({ email, password }, navigate) =>
async dispatch => {
return jwtService
.signInWithEmailAndPassword(email, password)
.then(user => {
navigate('/dashboard');
return dispatch(loginSuccess());
})
.catch(error => {
return dispatch(loginError(error));
});
};
...
const Login = () => {
const navigate = useNavigate();
function handleSubmit(model) {
dispatch(submitLogin(model, navigate));
}
return (
<Formsy onValidSubmit={handleSubmit} ref={formRef}>
<input type="text" placeholder="username" />
....
</Formsy>
);
}
Chain/await the returned Promise
export const submitLogin = ({ email, password }) =>
async dispatch => {
return jwtService
.signInWithEmailAndPassword(email, password)
.then(user => {
dispatch(loginSuccess());
return user;
})
.catch(error => {
dispatch(loginError(error));
throw error;
});
};
...
const Login = () => {
const navigate = useNavigate();
async function handleSubmit(model) {
try {
await dispatch(submitLogin(model));
navigate('/dashboard');
} catch(error) {
// handle error, log, etc...
}
}
return (
<Formsy onValidSubmit={handleSubmit} ref={formRef}>
<input type="text" placeholder="username" />
....
</Formsy>
);
}
When you use react hooks , there are some rules you can't bypass them
You have to call useHook() at the root level of your component or
function
You can't make conditional useHook() call
I think but maybe i am wrong that error occurred in this part of your code
export const submitLogin =
({
email,
password
}) =>
async dispatch => {
const history = useNavigate(); // x Wrong you can't call inside another function
...
};

× TypeError: Cannot read property 'push' of undefined in react.js

I am trying to use the useHistory hook in react.js , i dont't understand why i am getting error can not react property push of undefined .
code:
import { useHistory } from "react-router-dom";
function App() {
const [loader, setLoader] = useState(false);
const [errMsg, setErrMsg] = useState("");
const [signinLoader, setsinginLoader] = useState(false);
const [opterror, setoptError] = useState("");
const history = useHistory()
useEffect(() => {
const userInfo = localStorage.getItem("userInfo");
if (userInfo) {
history.push("/users");
}
}, [history]);
here is complete code of my app.js file check the useState hook where i am trying to use useHistory hook but its not working , getting error cannot read push of undefined
import "./App.css";
import axios from "axios";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Signup from "./components/Signup";
import Signin from "./components/login";
import Users from "./components/users";
import { useState, useEffect } from "react";
import { useHistory } from "react-router";
function App() {
const [loader, setLoader] = useState(false);
const [errMsg, setErrMsg] = useState("");
const [signinLoader, setsinginLoader] = useState(false);
const [opterror, setoptError] = useState("");
const history = useHistory()
useEffect(() => {
const userInfo = localStorage.getItem("userInfo");
if (userInfo) {
history.push("/");
}
}, [history]);
const formDataSender = async (FormData) => {
setLoader(true);
try {
if (FormData) {
let res = await axios.post("/api/users", FormData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
if (res) {
setLoader(false);
console.log(res);
setTimeout(() => {
setErrMsg("");
}, 1000);
return setErrMsg(res.data.message);
}
return setErrMsg(true);
}
} catch (error) {
setErrMsg(true);
}
};
const timer = (message) => {
setTimeout(() => {
setoptError(message);
}, 1000);
};
const loginSender = async (formData) => {
if (formData) {
setsinginLoader(true);
try {
let res = await axios.post("/api/users/login", formData);
console.log(res);
if (res.data.message) {
localStorage.setItem("userInfo", JSON.stringify(res.data));
setsinginLoader(false);
setoptError("login successful !");
timer("");
return console.log(res);
}
setsinginLoader(false);
setoptError(res.data.showmessage);
timer("");
} catch (error) {
timer("");
setoptError("login failed !!");
}
}
};
return (
<Router>
<Switch>
<div className="App">
<Route path="/" exact>
<Signin
passtologinhandler={loginSender}
loader={signinLoader}
additionalInfo={opterror}
/>
</Route>
<Route path="/signup">
<Signup
passedToSignUpHandler={formDataSender}
loading={loader}
err={errMsg}
/>
</Route>
<Route path="/users">
<Users />
</Route>
</div>
</Switch>
</Router>
);
}
export default App;
package.json
Instead of passing the loginSender,signinLoader,opterror as props in Signin component. Move all the functionality into Signin component. So in the Signin component, you should have something like this:
export const Signin =(props)=>{
const [signinLoader, setsinginLoader] = useState(false);
const [opterror, setoptError] = useState("");
useEffect(() => {
const userInfo = localStorage.getItem("userInfo");
if (userInfo) {
history.push("/");
}
}, []);
const loginSender = async (formData) => {
if (formData) {
setsinginLoader(true);
try {
let res = await axios.post("/api/users/login", formData);
console.log(res);
if (res.data.message) {
localStorage.setItem("userInfo", JSON.stringify(res.data));
setsinginLoader(false);
setoptError("login successful !");
timer("");
return console.log(res);
}
setsinginLoader(false);
setoptError(res.data.showmessage);
timer("");
} catch (error) {
timer("");
setoptError("login failed !!");
}
}
};
....
}
App:
return (
<BrowserRouter>
<Switch>
<div className="App">
<Route path="/" exact>
<Signin/>
</Route>
<Route path="/signup">
<Signup/>
</Route>
<Route path="/users">
<Users />
</Route>
</div>
</Switch>
</BrowserRouter>
);
}
You should do the same thing for Signup.

Redirect not redirecting in a React application

I am trying to implement Redirect from react-router-dom and it's redirecting in the URL, but not re-rendering the corresponding component.
import React, {useEffect, useState} from 'react';
import axios from 'axios';
import * as OnfidoSDK from 'onfido-sdk-ui/dist/onfido.min.js';
import 'onfido-sdk-ui/dist/style.css';
import {Redirect} from 'react-router-dom';
const onfidoContainerId = 'onfido-sdk-wrapper';
const transmitAPI = 'third/party/api/url';
const useOnfidoFetch = (URL) => {
const [token, setToken] = useState();
const [id, setId] = useState();
const [isClear, setIsClear] = useState(false);
useEffect(() => {
axios
.get("http://localhost:5000/post_stuff")
.then((response) => response.data.data.data.json_data)
.then((json_data) => {
console.log("this is the json data", json_data);
const id = json_data.applicant_id;
const token = json_data.onfido_sdk_token;
setId(id);
setToken(token);
});
}, [URL]);
useEffect(() => {
if (!token) return;
console.log("this is working!");
onfidoOut = OnfidoSDK.init({
token,
containerId: "root",
steps: [
{
type: "welcome",
options: {
title: "Open your new bank account",
},
},
"document",
],
onComplete: function (data) {
console.log("everything is complete");
console.log("this is the applicant id", id);
let obj;
axios
.post("http://localhost:5000/post_id", {
applicant_id: id,
})
.then((response) => {
obj = response.data.data.data.json_data.result;
setReceivedResults(obj === "clear");
});
if (setReceivedResults) {
onfidoOut.tearDown();
return <Redirect to="/result" />
} else {
return null;
}
},
});
}, [id, token]);
};
export default function() {
const URL = `${transmitAPI}/anonymous_invoke?aid=onfido_webapp`;
const result = useOnfidoFetch(URL, {});
return (
<div id={onfidoContainerId} />
)
}
I am not getting any errors in console. This is the App.js file with all of my components:
import Landing from './components/Landing';
import Onfido from './components/Onfido';
import Result from './components/Result';
export default () => {
return (
<div>
<StylesProvider>
<BrowserRouter>
<Switch>
<Route exact path="/onfido" component={Onfido} />
<Route exact path="/result" component={Result} />
<Route path="/" component={Landing} />
</Switch>
</BrowserRouter>
</StylesProvider>
</div>
);
};
Redirect is a component that must be rendered in order to have an effect, you're returning it from the hook but not doing anything with it.
You're looking for history.push('/result'). It serves the same purpose, but instead of rendering a component responsible for the redirect, you do it programmatically by updating the history.
See the docs on the useHistory.

Resources