How to re-render a component based on state changing - javascript

I'm trying to redirect to login page if not logged when trying to access any components that require authentication.
While trying to use firebase auth, the auth object is not always initialised and there is a small delay so according to documentation, I have to use onAuthStateChanged() event listener which all works ok with the Nav bar which shows the signed in user.
However, when trying to to do the redirection for loggedin users, it's not working as the initial login dialog is being shown always as the state for authuser initially is not set and the routing seems to have already taken place. I seen a similar question (Firebase, Avoid Logged-in user to visit login page) here but don't really understand how I can use the suggestion cookies/querystrings from one of the comments when going directly to the url as there will still be small delay initially between the session value being set and rendering so don't see how it will work first time using that way. Totally new to React so hope this question makes sense.
PrivateRoute.js :
// This is used to determine if a user is authenticated and
// if they are allowed to visit the page they navigated to.
// If they are: they proceed to the page
// If not: they are redirected to the login page.
import React, {useState} from 'react'
import { Redirect, Route } from 'react-router-dom'
const PrivateRoute = ({ loggedInUser, component: Component, ...rest }) => {
console.log("Private Route, Logged User:"+JSON.stringify(loggedInUser))
return (
<Route
{...rest}
render={props =>
(loggedInUser) ? (
<Component {...props} />
) : (
<Redirect to={{ pathname: '/login', state: { from: props.location } }} />
)
}
/>
)
}
export default PrivateRoute;

I have never worked with firebase, but I am doing something like this.
Let's say I have custom hooks, where I am getting my token, login, logout functions.
Here is my app.js looks like. I am getting token if user authorized to access. If access granted it gets the token, then sets the routes and redirects to admin dashboard.
function App() {
const { token, login, logout } = useAuth();
let routes;
if (token) {
routes = (
<Switch>
<Redirect to="/dashboard" />
</Switch>
);
} else {
routes = (
<Switch>
<Redirect to="/login" />
<Route path="/" exact component={Layout} />
</Switch>
)
}
return (
<AuthContext.Provider
value={{
isLoggedIn: !!token,
token: token,
login: login,
logout: logout,
}}
>
<Navigation />
<Router>
<main>
{routes}
</main>
</Router>
</AuthContext.Provider>
);
}
And this how my nav looks like
const Navigation = () => {
const auth = useContext(AuthContext);
return (
<>
{ auth.isLoggedIn && (<AdminNavigation />) }
{ !auth.isLoggedIn && (<UserNavigation />) }
</>
);
};
This is how my SignIn component looks like
const SignIn = () => {
const auth = useContext(AuthContext);
const classes = useStyles();
const {
// eslint-disable-next-line no-unused-vars
isLoading, error, sendRequest, clearError,
} = useHttpClient();
const [password, setPassword] = useState('');
const [email, setEmail] = useState('');
const [isLoggedIn, setIsLoggedIn] = useState(true);
const updateInput = (event) => {
if (event.target.id.toLowerCase() === 'email') {
setEmail(event.target.value);
} else {
setPassword(event.target.value);
}
};
const handleSwitchMode = () => {
setIsLoggedIn((prevMode) => !prevMode);
};
const authSubmitHandler = async (event) => {
event.preventDefault();
setIsLoggedIn(true);
// auth.login();
if (isLoggedIn) {
try {
const responseData = await sendRequest(
`${API_URL}/admin/login`,
'POST',
JSON.stringify({
email,
password,
}),
{
'Content-Type': 'application/json',
},
);
setIsLoggedIn(false);
auth.login(responseData.token);
} catch (err) {
setIsLoggedIn(false);
}
} else {
try {
const responseData = await sendRequest(
`${API_URL}/admin/signup`,
'POST',
JSON.stringify({
// name,
email,
password,
}),
{
'Content-Type': 'application/json',
},
);
auth.login(responseData.token);
} catch (err) {
clearError();
}
}
};
return (
<Container component="main" maxWidth="xs">
<div className={classes.paper}>
<Typography component="h1" variant="h5">
{isLoggedIn ? 'Login' : 'Sign up'}
</Typography>
<form className={classes.form} noValidate>
{!isLoggedIn && (
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="name"
label="Your name"
autoFocus
onChange={updateInput}
/>
)}
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
autoFocus
value={email}
onChange={updateInput}
/>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
value={password}
autoComplete="current-password"
onChange={updateInput}
/>
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
onClick={authSubmitHandler}
>
{isLoggedIn ? 'Login' : 'Sign up'}
</Button>
<Grid container>
<Grid item xs>
<Link href="/" variant="body2">
Forgot password?
</Link>
</Grid>
<Grid item>
<Button
onClick={handleSwitchMode}
>
Dont have an account? Sign Up
</Button>
</Grid>
</Grid>
</form>
</div>
</Container>
);
Hope this helps.

Related

how do a set a boolean value to false from one react component to main app.js

trying to use the handle submit function to change the isAuthinticated to true from false thats on the main app.js file thats using react router.. all of the redux examples i look at are all using an app js file that has the onclick function on it not react router. thank you if you can help
function App () {
return (
<Router>
<div>
<Switch>
<Route exact path="/" component={Login} />
<Route exact path="/login" component={Login} />
<Route exact path="/signup" component={Signup} />
<PrivateRoute
exact path="/mainpage"
component={MainPage}
isAuthenticated={false}
/>
</Switch>
<Footer />
</div>
</Router>
);
}
export default App;
my login.js that has the click event
const Login = () => {
const history = useHistory()
const [state, setState] = useState({
email: '',
password: ''
});
const [validate, setValid] = useState({
validateEmail: '',
validatePassword: '',
})
const handleInputChange = event => setState({
...state,
[event.target.name]: event.target.value,
})
const handleSubmit = user => {
if(state.password === ''){
setValid({validatePassword:true})
}
if(state.email === '' ){
setValid({validateEmail:true})
}
axios.post(`auth/login`, state )
.then(res => {
console.log(res);
console.log(res.data);
if (res.status === 200 ) {
history.push('/mainpage');
}
})
.catch(function (error) {
console.log(error);
alert('Wrong username or password')
window.location.reload();
});
}
// console.log('state', state)
const {email, password } = state
const [popoverOpen, setPopoverOpen] = useState(false);
const toggle = () => setPopoverOpen(!popoverOpen);
return (
<>
<Container>
<Row>
<Col>
<img src={logo} alt="Logo" id="logo" />
<Button id="Popover1" type="button">
About Crypto-Tracker
</Button>
<Popover placement="bottom" isOpen={popoverOpen} target="Popover1" toggle={toggle}>
<PopoverHeader>About</PopoverHeader>
<PopoverBody>Your personalized finance app to track all potential cryptocurrency investments</PopoverBody>
</Popover>
</Col>
<Col sm="2" id="home" style={{height: 500}}>
<Card body className="login-card">
<Form className="login-form">
<h2 className="text-center">Welcome</h2>
<h3 className="text-center">____________</h3>
<FormGroup>
<Label for="exampleEmail">Email</Label>
<Input invalid={validate.validateEmail} onChange = {handleInputChange} value = {email} type="email" required name="email" placeholder="email" />
<FormFeedback>Please enter email</FormFeedback>
</FormGroup>
<FormGroup>
<Label for="examplePassword">Password</Label>
<Input invalid={validate.validatePassword} onChange = {handleInputChange} value = {password} type="password" required name="password" placeholder="password"/>
<FormFeedback>Please enter password</FormFeedback>
</FormGroup>
<Button onClick={()=> handleSubmit(state)} className="but-lg btn-dark btn-block">Login</Button>
<div className="text-center pt-3"> or sign in with Google account</div>
<Loginbutton />
<div className="text-center">
Sign up
<span className="p-2">|</span>
Forgot password
</div>
</Form>
</Card>
</Col>
</Row>
</Container>
</>
);
}
export default Login;
authslice.js using asyncthunk
import { createAsyncThunk, createSlice } from '#reduxjs/toolkit'
import { userAPI } from '../../../server/routes/authRoutes'
const fetchAuth = createAsyncThunk(
'auth/login',
async (userId, thunkAPI) => {
const response = await userAPI.fetchById(userId)
return response.data
}
)
const authSlice = createSlice({
name: 'isAuthenticated',
initialState: {
value: false,
},
reducers: {
// Authenticated: state => {
// Redux Toolkit allows us to write "mutating" logic in reducers. It
// doesn't actually mutate the state because it uses the Immer library,
// which detects changes to a "draft state" and produces a brand new
// immutable state based off those changes
// state.value = true;
// },
},
extraReducers: {
[fetchAuth.fulfilled]: state => {
// Add user to the state array
state.value = true
},
[fetchAuth.rejected]: state => {
// Add user to the state array
state.value = false
}
}
});
dispatch(fetchUserById(123))
// export const { increment, decrement, incrementByAmount } = counterSlice.actions;
This would be easy to achieve if you use some kind of global store to store such values. Typical options include Redux, Mobx, etc.
Define your isAuthenticated variable as a global store variable. mutate its value using corresponding package methods like Redux dispatch events or similar from your functions anywhere else in the app.
You can try it using Redux, creating a store to the login variables, and sharing it with the component App.js.

Why is state set to null immediately after setter function defined by useState is called?

I refactored my App.js into a functional component. When I try to login, my currentUser is set to a user, but then immediately set to null. I am confused why currentUser is set to null after it is given value. Is something calling setCurrentUser again to set it to null?
App.js:
const App = (props) => {
const [ currentUser, setCurrentUser ] = useState(null)
const [ shoppingCart, setShoppingCart ] = useState([])
const handleLogin = (email, password, history) => {
axios({
method: 'post',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
data: { email, password},
url: 'http://localhost:3000/api/v1/login'
})
.then( res => setCurrentUser(res.data.user))
}
console.log('this is currentUser', currentUser)
return (
<Switch>
<div>
<SideDrawer currentUser={currentUser} setCurrentUser={setCurrentUser}/>
<div className='App'>
{/** OTHER ROUTES HERE **/}
<Route path='/login' render={
() => {
return (
<Login handleLogin={handleLogin} history={props.history} currentUser={currentUser}/>
)
}
} />
{/* Route to Signup page */}
<Route path='/signup' render={
() => {
return(
<SignupForm setCurrentUser={setCurrentUser} history={props.history}/>
)
}
} />
</div>
</div>
</Switch>
Login.js
const Login = ({history, handleLogin}) => {
const classes = useStyles()
const [ values, setValues ] = useState({
email: '',
password: '',
showPassword: false
})
const handleChange = e => {
const { name, value } = e.target
setValues({ ...values, [name]: value})
}
const handleShowPassword = () => {
setValues({...values, showPassword: !values.showPassword})
}
const handleMouseDownPassword = (e) => {
e.preventDefault()
}
return (
<Box className={classes.container}>
<h1>Login</h1>
<FormGroup>
<FormControl variant="outlined">
<TextField
className={classes.text}
variant='outlined'
multiline
name='email'
label="Email"
onChange={handleChange}
/>
</FormControl>
<FormControl variant='outlined'>
<TextField
label='Password'
className={classes.text}
type={values.showPassword ? 'text' : 'password'}
name='password'
margin="normal"
variant='outlined'
onChange={handleChange}
InputProps={{
endAdornment: (
<InputAdornment>
<IconButton
onClick={handleShowPassword}
onMouseDown={handleMouseDownPassword}
>
{values.showPassword ? <Visibility /> : <VisibilityOff />}
</IconButton>
</InputAdornment>
)
}}
/>
</FormControl>
<Button
variant='contained'
className={classes.button}
onClick={ () => handleLogin(values.email, values.password, history)}
>
Login
</Button>
</FormGroup>
</Box>
)
}
Something is setting it to null.
Either:
.then( res => setCurrentUser(res.data.user))
or SideDrawer or SignupForm are calling setCurrentUser(null).
If you remove both SideDrawer and SignupForm you can check the functionality of the .then( res => setCurrentUser(res.data.user)) line.
Then add back SideDrawer and see if that is causing it to be set to null. Lastly, add back SignupForm and see if that's the culprit.

React Router not rendering page

I have a component called admin it is a form that will redirect me to another page rendering not working though.
Router main
const globalState = {
isAuthed: false,
token: null,
};
export const AuthContext = React.createContext(globalState);
function App() {
const [currentUser, setCurrentUser] = useState(globalState)
return (
<AuthContext.Provider value={[currentUser, setCurrentUser]}>
<Router>
<Switch>
<Route exact path="/admin" component={Admin} />
<Route exact path="/admin-panel" component={Pannel} />
</Switch>
</Router>
</AuthContext.Provider>
)
}
export default App;
admin component
const LoginForm = () => {
const [state, setState] = useContext(AuthContext)
const login = (state) => {
const user = document.getElementById('user').value;
const pass = document.getElementById('pass').value;
const request = {
user,
pass
}
console.log(request)
fetch('/api/admin', {
method: "post",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(request),
})
.then(res => res.json())
.then(res => {
if(res.auth){
valid(5000,"Login Success. Redirecting in 3 second")
setTimeout(() =>{
setState({isAuthed: res.auth, token: res.key})
}, 3000)
}
else{
warn(5000,res.message)
}
})
}
return(
<div style={css}>
<ToastContainer />
{(state && state.isAuthed)? <Redirect to='/adming-panel'/>: false}
<h1 style={{color: "teal"}}>Admin Panel</h1>
<Form id="login-form" size='large' style={{backgroundColor: "white"}}>
<Segment stacked>
<Form.Input id="user" fluid icon='user' iconPosition='left' placeholder='E-mail address' />
<Form.Input
fluid
icon='lock'
iconPosition='left'
placeholder='Password'
type='password'
id="pass"
/>
<Button onClick={() => login(state)} color='teal' fluid size='large'>
Login
</Button>
</Segment>
</Form>
</div>
)
}
export default LoginForm
the new page that I want to render
const Pannel = () => {
const [state, setState] = useContext(AuthContext)
return (
<div>
{(!state || !state.isAuthed)? <Redirect to='/adming-panel'/>: false}
Secret Page
</div>
)
}
export default Pannel
All the answers that I searched for. Was to put the exact keyword before the path but still, the component won't render only an empty white screen appears and no errors on console or backend console.
<Route exact path="/admin-panel" component={Pannel} />
Spot the key difference
<Redirect to='/adming-panel'/>
You are welcome.

Issue in Redirection From Login Screen

When the form is submitted, I run a GraphQL mutation. If it's successful, I want to redirect to a private page /panel after a token is returned and stored in local storage. If not, I want to show an error message from my StatusMessage()function.
The issue is that if login is unsuccessful, the error message works fine. But if the login is successful, I still get redirected to /404instead of /panel. However, when I go back to my /loginpage, I am automatically redirected to /panel this time. I don't know what goes wrong on the first time. Maybe the token is returned a few seconds late and redirection happens earlier?
Is there a solution to this? Here's my code:
function LoginPage (props: any){
const [isSubmitted, setIsSubmitted] = useState(false);
const [errorMessage, setErrorMessage] = useState('');
const [shouldRedirect, setShouldRedirect] = useState(false);
const [removeUser] = useMutation(LoginMutation);
// useEffect(() => {
// if(localStorage.getItem('token')){
// setShouldRedirect(true);
// },[] );
function submitForm(email: string, password: string) {
setIsSubmitted(true);
removeUser({
variables: {
email: email,
password: password,
},
}).then(({ data }: any) => {
localStorage.setItem('token', data.loginEmail.accessToken);
setShouldRedirect(true);
//props.history.push("/panel");
})
.catch((error: { message: string; }) => {
setShouldRedirect(false);
console.log("Error msg:" + error.message);
setErrorMessage(error.message);
})
}
if(shouldRedirect) return <Redirect to="/panel" />;
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center'
}}>
<Avatar>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<Formik
initialValues={{ email: '', password: '' }}
onSubmit={(values, actions) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
actions.setSubmitting(false);
}, 1000);
}}
validationSchema={schema}
>
{props => {
const {
values: { email, password },
errors,
touched,
handleChange,
isValid,
setFieldTouched
} = props;
const change = (name: string, e: any) => {
e.persist();
handleChange(e);
setFieldTouched(name, true, false);
};
return (
<form style={{ width: '100%' }}
onSubmit={e => {e.preventDefault();
submitForm(email, password);}}>
<TextField
variant="outlined"
margin="normal"
id="email"
fullWidth
name="email"
helperText={touched.email ? errors.email : ""}
error={touched.email && Boolean(errors.email)}
label="Email"
value={email}
onChange={change.bind(null, "email")}
/>
<TextField
variant="outlined"
margin="normal"
fullWidth
id="password"
name="password"
helperText={touched.password ? errors.password : ""}
error={touched.password && Boolean(errors.password)}
label="Password"
type="password"
value={password}
onChange={change.bind(null, "password")}
/>
{isSubmitted && StatusMessage(shouldRedirect, errorMessage)}
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
<br />
<Button className='button-center'
type="submit"
disabled={!isValid || !email || !password}
>
Submit</Button>
<br></br>
<Grid container>
<Grid item xs>
<Link href="#" variant="body2">
Forgot password?
</Link>
</Grid>
</form>
)
}}
</Formik>
</div>
{/* {submitted && <Redirect to='/panel'/>} */}
</Container>
);
}
export default LoginPage;
Edit: This is how I am doing private routing:
const token = localStorage.getItem('token');
export const PrivateRoute = ({component, isAuthenticated, ...rest}: any) => {
const routeComponent = (props: any) => (
isAuthenticated
? React.createElement(component, props)
: <Redirect to={{pathname: '/404'}}/>
);
return <Route {...rest} render={routeComponent}/>;
};
export default function App() {
return (
<div>
<BrowserRouter>
<Switch>
<Route exact path='/' component= {HomePage}></Route>
<Route path='/login' component= {LoginPage}></Route>
<PrivateRoute
path='/panel'
isAuthenticated={token}
component={PanelHomePage}
/>
<Redirect from='*' to='/404' />
</Switch>
</BrowserRouter>
</div>
);
}
You are reading token only on script load. So once user logs in the app via login form, he is redirected to 404 because you are not rereading token from localstorage. Once you refresh page, you have token and therefore user gets login.
That however won't solve all your problems, because you are not rerendering app. You have to have isLoggedIn check somewhere in the app, to make sure you rerender component.

Using React Router to Redirect to next page after successful login

I have created a basic MERN log in page and I am a bit confused on how to redirect the user after a successful log in. I have created a Log in context and when a user successfully logs in I set logged in state to true. I am unsure how I can then redirect to /items route. Any help would be appreciated. Here is my App code:
function App() {
return (
<LoggedInProvider>
<ThemeProvider>
<Switch>
<Route
exact
path="/"
render={() => <SignIn />}
/>
<Route
exact
path="/items"
render={() => <Index />}
/>
</Switch>
</ThemeProvider>
</LoggedInProvider>
);
}
export default App;
Here is my SignIn component:
function Form(props) {
const { isDarkMode } = useContext(ThemeContext);
const { loggedIn, changeLogIn } = useContext(LoggedInContext);
const [isSignUp, setSignUp] = useState(false);
const { classes } = props;
const [usernameValue, setUsernameValue] = useState('');
const [passwordValue, setPasswordValue] = useState('');
const handleUsernameChange = (e) => {
setUsernameValue(e.target.value);
};
const handlePasswordChange = (e) => {
setPasswordValue(e.target.value);
};
// const [value, setValue] = useState(initialVal);
// const handleChange = (e) => {
// setValue(e.target.value);
// };
const handleClick = () => {
setSignUp(!isSignUp);
};
const reset = () => {
setUsernameValue('');
setPasswordValue('');
};
const authSubmitHandler = async (event) => {
event.preventDefault();
if (!isSignUp) {
try {
const response = await fetch('http://localhost:8181/auth', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: usernameValue,
password: passwordValue,
}),
});
const responseData = await response.json();
if (responseData.code === 200) {
console.log('Success Response');
changeLogIn(true);
reset();
}
console.log('This is a response');
console.log(responseData);
} catch (err) {
console.log(err);
}
} else {
try {
const response2 = await fetch('http://localhost:8181/auth', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: usernameValue,
password: passwordValue,
}),
});
const responseData2 = await response2.json();
console.log(responseData2);
} catch (err) {
console.log(err);
}
}
};
return (
<main className={classes.main}>
{!isSignUp ? (
<Paper
className={classes.paper}
style={{ background: isDarkMode ? '#2E3B55' : 'white' }}
>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography variant="h5">Sign In</Typography>
<form
className={classes.form}
onSubmit={authSubmitHandler}
>
<FormControl
margin="normal"
required
fullWidth
>
<InputLabel htmlFor="username">Username</InputLabel>
<Input
id="username1"
name="username1"
value={usernameValue}
onChange={handleUsernameChange}
autoFocus
/>
</FormControl>
<FormControl
margin="normal"
required
fullWidth
>
<InputLabel htmlFor="password">Password</InputLabel>
<Input
id="password"
name="password"
type="password"
value={passwordValue}
onChange={handlePasswordChange}
autoFocus
/>
</FormControl>
<Button
variant="contained"
type="submit"
fullWidth
color="primary"
className={classes.submit}
>
Sign In
</Button>
</form>
<Button
variant="contained"
type="submit"
fullWidth
color="secondary"
className={classes.submit}
onClick={handleClick}
>
Switch to Sign up
</Button>
</Paper>
) : (
<Paper
className={classes.paper}
style={{ background: isDarkMode ? '#2E3B55' : 'white' }}
>
<Avatar className={classes.avatar}>
<LockOutlinedIcon color="primary" />
</Avatar>
<Typography variant="h5">Sign Up</Typography>
<form
className={classes.form}
onSubmit={authSubmitHandler}
>
<FormControl
margin="normal"
required
fullWidth
>
<InputLabel htmlFor="username">Username</InputLabel>
<Input
id="username2"
name="username"
value={usernameValue}
onChange={handleUsernameChange}
autoFocus
/>
</FormControl>
<FormControl
margin="normal"
required
fullWidth
>
<InputLabel htmlFor="password">Password</InputLabel>
<Input
id="password"
name="password"
type="password"
value={passwordValue}
onChange={handlePasswordChange}
autoFocus
/>
</FormControl>
<Button
variant="contained"
type="submit"
fullWidth
color="primary"
className={classes.submit}
>
Sign Up
</Button>
</form>
<Button
variant="contained"
type="submit"
fullWidth
color="secondary"
className={classes.submit}
onClick={handleClick}
>
Switch to Sign In
</Button>
</Paper>
)}
</main>
);
}
// class Form extends Component {
// static contextType = LanguageContext;
// render() {
// return (
// );
// }
// }
export default withStyles(styles)(Form);
And here is my log in context:
import React, { createContext, useState } from 'react';
export const LoggedInContext = createContext();
export function LoggedInProvider(props) {
const [loggedIn, setLoggedIn] = useState(false);
const changeLogIn = (val) => {
setLoggedIn(val);
};
return (
<LoggedInContext.Provider value={{ loggedIn, changeLogIn }}>
{props.children}
</LoggedInContext.Provider>
);
}
In your LoggedInProvider component you can do something like this:
import { useHistory } from "react-router-dom";
import React, { createContext, useState } from "react";
export const LoggedInContext = createContext();
export function LoggedInProvider(props) {
const history = useHistory();
const [loggedIn, setLoggedIn] = useState(false);
const changeLogIn = (val) => {
setLoggedIn(val);
if(val) NavigateAway('/items');
};
const NavigateAway = path => {
history.push(path);
}
return (
<LoggedInContext.Provider value={{ loggedIn, changeLogIn }}>
{props.children}
</LoggedInContext.Provider>
);
}
Hope this work's for you.
Just use props.history.push(). Every route's component will have access to the history object attached to it. As a reference:
const Login = ({ history }) => {
// username, password state fields here
function login(e) {
e.preventDefault();
login({ username, password })
.then(() => {
// set your authentication credentials to some persistent store
history.push('/items');
});
}
return (
// login form markup in here
);
};
well, the easiest way to do is to use the history object available in your props.
Try to see if it exist, you can do the following:
this.props.history.push('/item'): this should redirect you to the page.
Link from react-router-dom: it contains a property called redirect

Categories

Resources