Перенаправление на предыдущую страницу в ReactJS

У меня проблема с перенаправлением на предыдущую страницу, так как я делаю проверку isLoggedIn. Проблема сейчас в том, что после проверки isLoggedIn он перенаправляется на маршрут по умолчанию. Как мне поддерживать страницу, на которой я нахожусь? Что я сделал прямо сейчас, так это использовал referer, но он не определен. Пожалуйста, помогите мне найти другой способ. Пожалуйста, проверьте мой код ниже:

Логин.js

const Form = (props) => {
    const classes = useStyles();
    const isLoggedIn = useSelector((state) => state.auth.isLoggedIn);
    const referer = props.referer;
    const history = useHistory();

    console.log(history);

    const { values, touched, errors, isSubmitting, handleChange, handleBlur, handleSubmit } = props;

    if (isLoggedIn) {
      return <Redirect to={referer} />;
    }

    return (
      <div className={classes.root}>
        <Grid container direction="row" justify="center">
          <Grid item lg={4} md={5} xs={10}>
            <Card>
              <form onSubmit={handleSubmit}>
                <CardHeader
                  title="LOGIN"
                  classes={{
                    title: classes.cardHeader,
                  }}
                  className={classes.cardHeader}
                />

                <CardContent className={classes.textFieldSection}>
                  <TextField
                    fullWidth
                    label="Username"
                    name="username"
                    type="text"
                    variant="outlined"
                    value={values.username}
                    onChange={handleChange}
                    onBlur={handleBlur}
                    helperText={touched.username ? errors.username : ''}
                    error={touched.username && Boolean(errors.username)}
                    InputProps={{
                      endAdornment: (
                        <InputAdornment>
                          <AccountCircle />
                        </InputAdornment>
                      ),
                    }}
                  />
                  <TextField
                    fullWidth
                    label="Password"
                    name="password"
                    style={{ marginTop: '1rem' }}
                    type="password"
                    variant="outlined"
                    value={values.password}
                    onChange={handleChange}
                    onBlur={handleBlur}
                    helperText={touched.password ? errors.password : ''}
                    error={touched.password && Boolean(errors.password)}
                    InputProps={{
                      endAdornment: (
                        <InputAdornment>
                          <LockIcon />
                        </InputAdornment>
                      ),
                    }}
                  />
                </CardContent>

                <CardActions className={classes.loginButtonSection}>
                  <Button
                    type="submit"
                    color="primary"
                    variant="contained"
                    className={classes.loginButton}
                    disabled={isSubmitting}
                  >
                    Log In
                  </Button>
                </CardActions>

              </form>
            </Card>
          </Grid>
        </Grid>
      </div>
    );
  };

  let yup = require('yup');

  export const Login = (props) => {
    const dispatch = useDispatch();

    const MyFormWithFormik = withFormik({
      mapPropsToValues: ({ username, password }) => {
        return {
          username: username || '',
          password: password || '',
        };
      },
      validationSchema: yup.object().shape({
        username: yup.string().required('Enter your username'),
        password: yup.string().required('Enter your password'),
      }),
      handleSubmit: (values, { setSubmitting }) => {
        dispatch(login(values.username, values.password));
        setSubmitting(false);
      },
    })(Form);

    return <MyFormWithFormik />;
  };

  Form.propTypes = {
    className: PropTypes.string,
  };

  export default Login;

PrivateRoute.js

import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import axios from 'axios';
import { useSelector } from 'react-redux';

function PrivateRoute({ component: Component, ...rest }) {
  const authTokens = useSelector((state) => state.auth.access_token);

  function checkTokenExpiry() {
    if (authTokens) {
      axios.interceptors.request.use(
        function (config) {
          const token = `Bearer ${authTokens}`;
          config.headers.Authorization = token;
          console.log(config);
          return config;
        },
        (error) => {
          console.log(error);
          Promise.reject(error);
        }
      );
    }
  }

  if (authTokens != null) {
    checkTokenExpiry();
  }

  return (
    <Route
      {...rest}
      render={(props) =>
        authTokens ? (
          <Component {...props} />
        ) : (
          <Redirect to={{ pathname: '/login', state: { referer: props.location } }} />
        )
      }
    />
  );
}

export default PrivateRoute;

PrivateAdminOnlyRoute

import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import axios from 'axios';
import { useSelector } from 'react-redux';

function PrivateAdminOnlyRoute({ component: Component, ...rest }) {
  const authTokens = useSelector((state) => state.auth.access_token);
  const isAdmin = useSelector((state) => state.auth.is_admin);

  function checkTokenExpiry() {
    if (authTokens) {
      axios.interceptors.request.use(
        function (config) {
          const token = `Bearer ${authTokens}`;
          config.headers.Authorization = token;
          console.log(config);
          return config;
        },
        (error) => {
          console.log(error);
          Promise.reject(error);
        }
      );
    }
  }

  if (authTokens != null) {
    checkTokenExpiry();
  }

  return (
    <Route
      {...rest}
      render={(props) =>
        authTokens && isAdmin === true ? (
          <Component {...props} />
        ) : authTokens && (isAdmin === false || undefined || null) ? (
          <Redirect to={{ pathname: '/pending', state: { referer: props.location } }} />
        ) : (
          <Redirect to={{ pathname: '/login', state: { referer: props.location } }} />
        )
      }
    />
  );
}

export default PrivateAdminOnlyRoute;

Routes.js

import React, { useState } from 'react';
import { BrowserRouter as Router, Link, Route, Switch } from 'react-router-dom';
import PrivateRoute from './PrivateRoute';
import Login from './pages/Login/Login';
import Signup from './pages/Signup/Signup';
import Common from './pages/Common';

function Routes() {
  return (
    <Router>
      <Switch>
        <Route path="/login" component={Login} />
        <Route path="/signup" component={Signup} />
        <PrivateRoute path="/" component={Common} />
      </Switch>
    </Router>
  );
}

export default Routes;

person Joseph    schedule 03.06.2020    source источник
comment
ты пробовал history.goBack(); ?   -  person Hagai Harari    schedule 03.06.2020
comment
@Хагай Харари. Да, в нем есть ошибки.   -  person Joseph    schedule 03.06.2020
comment
какие ошибки? Вы можете добавить эту попытку и потерпеть неудачу к своему вопросу?   -  person Hagai Harari    schedule 03.06.2020
comment
@Хагай Харари. Извините, ошибки нет, но перенаправляет на страницу входа   -  person Joseph    schedule 03.06.2020
comment
пожалуйста, добавьте свою декларацию Router и способ перехода в Login с экрана, к которому вы хотите вернуться, к вашему вопросу   -  person Hagai Harari    schedule 03.06.2020
comment
@Хагай Харари. Привет только что добавил. просто скажите мне, если его не хватает, или вы добавите больше рекомендаций/предложений. Спасибо   -  person Joseph    schedule 03.06.2020


Ответы (1)


Использование state внутри Redirect связано не с state с props, а с location


      import { useLocation } from 'react-router-dom';


      const location = useLocation();
      const referer = location.state && location.state.referer

еще одна вещь о вашем коде (который не связан напрямую с вашей проблемой)

(isAdmin === false || undefined || null)

isAdmin сравнивается только с false, а в случае, если isAdmin не является false, он не сравнивается с undefined, но undefined стоит сам по себе (с ложным поведением...), и то же самое касается null

надеюсь, это полезно :)

person Hagai Harari    schedule 03.06.2020
comment
Я бы сделал что-то вроде authTokens && !isAdmin, что оценивается как true для всех ложных значений, и извините, приятель, я действительно не следил за вашим вторым вопросом. - person Hagai Harari; 03.06.2020
comment
на каком пути вы обновляете? - person Hagai Harari; 03.06.2020
comment
Я не уверен .. вы можете создать песочницу? - person Hagai Harari; 03.06.2020
comment
Я думаю, это потому, что его проверка isLoggedIn. Я думаю, нам нужно что-то добавить в App.js? Вот так на картинке ibb.co/VxV9p8v - person Joseph; 03.06.2020
comment
о вашем первом выпуске, может быть, открыть для него новый вопрос? здесь начинается беспорядок.. о второй проблеме - title="cannot read property someproperty of undefined in response"> stackoverflow.com/questions/61279604/, просто адаптируйте код, который использует this.props.location, к вашему использованию location - person Hagai Harari; 03.06.2020
comment
Ok. Можете ли вы отредактировать свой код в этой части this.props.location. Реферер не определен. Спасибо. - person Joseph; 03.06.2020
comment
Привет! Извините, но ошибка та же Cannot read property 'referer' of undefined - person Joseph; 03.06.2020
comment
Спасибо. Я просто опубликую еще один вопрос для другого. Спасибо - person Joseph; 03.06.2020