Passionate Engineer
Passionate Engineer

Reputation: 10412

history push does not match Route. Only changes the URL and defaults to catch all route instead

I have React Router v5 with below code:

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';

const muiTheme = createMuiTheme({
  palette: {
    primary: {
        main: '#2196f3'
    }
  },
  overrides: {
    MUIDataTableSelectCell: {
      fixedHeaderCommon: {
        backgroundColor: 'transparent',
      },
    },
    MuiTableCell: {
      sizeSmall: {
        padding: '6px 0 6px 16px'
      }
    },
    MuiTableRow: {
      hover: {
        cursor: 'pointer'
      }
    }
  }
});

ReactDOM.render(<MuiThemeProvider theme={muiTheme}><App /></MuiThemeProvider>, document.getElementById('root'));

serviceWorker.unregister();

App.js

import {
  // BrowserRouter as Router,
  Switch,
  Route,
  Router,
  // Link,
  // useRouteMatch,
  // useParams
} from "react-router-dom";
import history from 'history/browser';
import Dashboard from './common/components/Dashboard';
import Login from './common/components/Login';
import Test from './common/components/Test';


<Router history={history}>
  <Switch>
    <Route path="/test" component={Test} />
    <Route path="/login" component={Login} />
    <Route path="/" exact component={Dashboard} />
    <Route component={Error404} />
  </Switch>
</Router>

Login.js

import { useHistory } from "react-router-dom";

export default function Login() {
  let history = useHistory();
  const classes = useStyles();
  const storedToken = localStorage.getItem('token');
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [remember, setRemember] = useState(false);
  const [fetchError, setFetchError] = useState(null);

  async function login(e) {
    e.preventDefault();
    try {
      const data = await ApiClient.post(`/api/auth`, { email: email, password: password, remember: remember });
      localStorage.setItem('token', data.token);
      setFetchError(null);
      history.push('/test');
    } catch (err) {
      if(err.response.status === 401) {
        setFetchError('Unauthorized access, please login again.');
      }
    }
  }

  return (
    <Container component="main" maxWidth="xs">
      <CssBaseline />
      <div className={classes.paper}>
        <Avatar className={classes.avatar}>
          <LockOutlinedIcon />
        </Avatar>
        <Typography component="h1" variant="h5">
          Login
        </Typography>
        <form className={classes.form} noValidate onSubmit={login}>
          <TextField
            variant="outlined"
            margin="normal"
            required
            fullWidth
            id="email"
            label="Email Address"
            name="email"
            autoComplete="email"
            autoFocus
            onChange={(e) => setEmail(e.target.value)}
            value={email}
          />
          <TextField
            variant="outlined"
            margin="normal"
            required
            fullWidth
            name="password"
            label="Password"
            type="password"
            id="password"
            autoComplete="current-password"
            onChange={(e) => setPassword(e.target.value)}
            value={password}
          />
          <FormControlLabel
            control={<Checkbox value="remember" color="primary" />}
            label="Remember me"
            onChange={(e) => setRemember(e.target.value)}
            value={remember}
          />
          <Button
            type="submit"
            fullWidth
            variant="contained"
            color="primary"
            className={classes.submit}
          >
            Sign In
          </Button>
          <Grid container>
            <Grid item xs>
              <Link href="#" variant="body2">
                Forgot password?
              </Link>
            </Grid>
            <Grid item>
              <Link href="#" variant="body2">
                {"Don't have an account? Sign Up"}
              </Link>
            </Grid>
          </Grid>
        </form>
      </div>
      <Box mt={8}>
        <Copyright />
      </Box>
    </Container>
  );

}

Whenever I submit with correct credentials I get 200 response code from the server with JWT token but after history.push('/test'); on login function, I don't get the Route match with /test instead it goes to Error404 catch all route.

How is this possible?

Upvotes: 1

Views: 588

Answers (1)

Passionate Engineer
Passionate Engineer

Reputation: 10412

It seems like a bug in history version 5. See this comment. When I downgraded to 4.10.1 it immediately worked

Upvotes: 1

Related Questions