Search code examples
reactjstypescriptamazon-cognitoaws-amplify

Is it possible to trigger function after logging in by withAuthenticator() of AWS Amplify?


I would like to trigger function when user login by withAuthenticator() of Amplify. (I need to send state data to other component by contextAPI of React.js)

I've found explanation of SignIn() function, but I didn't find something about function when users login

▼Main.tsx (Main page, everyone can watch)

import React from 'react';
import { BrowserRouter as Router, Route } from "react-router-dom";
import Login from './Login';
import Mypage from './mypage/Index';
import Menu from './Menu';
import Hoge from './Hoge';

class Main extends React.Component {

    render(){
        return (
            <div className="Main">
                <Router>
                    <Menu />

                     //**Mypage ← only logged in can watch
                    <Route exact path="/mypage" component={Mypage} />
                    <Route path="/main" component={Hoge} />
                </Router>
            </div>
        );
    }
}

export default Main;

▼mypage.tsx (looged in users can watch)

import React from 'react';
import { RouteComponentProps, Link } from 'react-router-dom';
import { withAuthenticator } from 'aws-amplify-react';
import Auth from '@aws-amplify/auth';
import AuthContext from '../context/auth-context';

interface MatchParams {
    id: number;
}

interface State {
    user: '',
}

class Mypage extends React.Component<RouteComponentProps<MatchParams>, State> {
    constructor(props: RouteComponentProps) {
        super(props);
        this.state = { user: '' };
    }

    async componentDidMount() {
        let user = await Auth.currentAuthenticatedUser()
        this.setState({user: user.username});
    }

   //**(it's just what I want now)
   //loggedIn() {
   //     console.log("logged in!");
   //}

    render() {
        return (
            <div className="mypage">
                <h1>mypage</h1>
                <div>
                    <ul>
                        <li><Link to='hoge'>hoge</Link></li>
                    </ul>
                </div>
            </div>
        );
    }
}

export default withAuthenticator(Mypage);

Answer to J.Hesters

・your ideas 1,2

actually I thought about these ideas(creating signIn form myself), but I wanted to know how it works without them (i should have write about it at first time)

・your idea 3

I inserted console.log("login in!!") in componentDidUpate() but it didnt work after login

Maybe I gotta use the way 1 or 2, but if you get why it doesnt work ur idea3, plz write it here Anyway thx for answering sir ^^


Solution

  • You can just write whatever code you want to execute after the await keyword.

    async componentDidMount() {
      let user = await Auth.currentAuthenticatedUser();
      this.setState({user: user.username});
      console.log('logged in.');
    }
    

    Edit:

    As far as I know, you can't explicitly overwrite withAuthenticator's methods. So you have three options as far as I'm concerned:

    1. Supply a custom <SignIn /> component to with authenticator in which you handle the login process manually and invoke whatever function you like as soon as the login method finishes.
    2. Write the whole UI login UI yourself and use Amplify's Auth methods explicitly whenever you need to. Here is an example repository doing it.
    3. Use componentDidUpdate() to trigger code after the component rerenders when the user logs in. Be careful to not create infinite loops with setState. componentDidUpdate only gets called, when the component rerenders. Components within withAuthenticator don't neccesarily rerender.