Hope whoever is reading is having a great day, or night considering were coders ;)
Anyway, down to the problem at hand. I have been diving deep into new territory recently while setting up my first application. I am using React, AWS Amplify and serverless functions hooked up to API Gateway to run the back end.
Right now I am having trouble with my login system, it used to work perfectly (except for a bug in the AWS amplify SDK that prevented persistent user authorisation), I was able to log in and I could register new accounts. However since I couldn't stay logged in I added a little code to bypass the authorisation process while I was developing. Now that I need to access the user object for use in my API I removed the little bypass code and now I am getting a Maximum Depth Exceeded Error whenever I try to load the component responsible for Authentication (see below).
I have narrowed it down to my Authentication component as I can console log comments all the way up until the end of the constructor for Authentication. The issue seems to be in the componentDidMount() function right after the call to Auth (see comment below) however if I comment out that entire function I still get the same error.
I can't figure out what I am doing wrong here and I am hoping that a wise coder here on Stack will be able to help me out, I have included the Authentication component below as well as a link to my Github that contains the rest of the code if you require it.
Please ask any questions if you need anything
Thank you in advance to whoever is reading :)
Authentication Component
// Modules
import React from 'react';
import {Auth} from 'aws-amplify';
import {BrowserRouter as Router, Switch, Route, Redirect} from 'react-router-dom';
import Application from 'components/pages/Application';
import Login from 'components/pages/Login';
import Register from 'components/pages/Register';
class Authentication extends React.Component {
constructor(props) {
super(props);
this.state = {
username: '',
email: '',
password: '',
phone_number: '',
confirmcode: '',
user: null,
isAuthenticated: false
}
this.handleFormInput = this.handleFormInput.bind(this);
this.setAuthenticated = this.setAuthenticated.bind(this);
}
async componentDidMount() {
if (!this.state.isAuthenticated) {
try {
const CAURes = await Auth.currentAuthenticatedUser({bypassCache: true});
let user = {
username: CAURes.username,
...CAURes.attributes
}
if (user.email_verifed) {
this.setState({user: user, isAuthenticated: true});
}
} catch (error) {
console.error(error);
}
}
}
handleFormInput(event) {
this.setState({
[event.target.name]: event.target.value
});
};
setAuthenticated() {
this.setState({
isAuthenticated: true
});
}
render() {
return (
<Router>
<Switch>
<PrivateRoute path='/'
component={Application} isAuthenticated={this.state.isAuthenticated} userData={this.state.user} />
<Route exact path='/login'
render={(props) => <Login {...props} handleFormInput={this.handleFormInput} formInputs={this.state} setAuthenticated={this.setAuthenticated} />} />
<Route exact path='/register'
render={(props) => <Register {...props} handleFormInput={this.handleFormInput} formInputs={this.state} setAuthenticated={this.setAuthenticated} />} />
</Switch>
</Router>
);
}
}
const PrivateRoute = ({ component: Component, isAuthenticated, ...rest }) => {
return(
<Route {...rest} render={(props) => {
return(
isAuthenticated === true
? <Component {...props} {...rest} />
: <Redirect to={{
pathname: '/login',
state: { from: props.location }
}} />
)
}}/>
);
}
export default Authentication;
GitHub with additional code if needed :)
Because of React router's partial matching, /
, matches all other routes.
You can either add exact
in your PrivateRoute
like other routes:
<PrivateRoute exact path='/' ... >
or, if you don't want to, move PrivateRoute
to the end of the routes like so:
render() {
return (
<Router>
<Switch>
<Route exact path='/login'
render={(props) => <Login {...props} handleFormInput={this.handleFormInput} formInputs={this.state} setAuthenticated={this.setAuthenticated} />} />
<Route exact path='/register'
render={(props) => <Register {...props} handleFormInput={this.handleFormInput} formInputs={this.state} setAuthenticated={this.setAuthenticated} />} />
<PrivateRoute path='/'
component={Application} isAuthenticated={this.state.isAuthenticated} userData={this.state.user} />
</Switch>
</Router>
);
}