Rewrote app to use hooks and fixed multiple re-renders.

This commit is contained in:
Patrick Fic
2019-12-11 18:39:27 -08:00
parent 5c7523e6bd
commit f333301f67
16 changed files with 162 additions and 193 deletions

View File

@@ -1,6 +1,4 @@
import React, { Component } from "react";
import { Mutation, Query } from "react-apollo";
import { GET_CURRENT_USER, SET_CURRENT_USER } from "../graphql/local.queries";
import App from "./App";
import Spin from "../components/loading-spinner/loading-spinner.component";
@@ -72,29 +70,17 @@ class AppContainer extends Component {
}
middlewares.push(authLink.concat(link));
const cache = new InMemoryCache({ addTypename: false });
const cache = new InMemoryCache();
const client = new ApolloClient({
link: ApolloLink.from(middlewares),
cache,
typeDefs,
resolvers,
defaultOptions: {
watchQuery: {
fetchPolicy: "cache-and-network",
errorPolicy: "ignore"
},
query: {
fetchPolicy: "cache-and-network",
errorPolicy: "all"
}
}
resolvers
});
client.writeData({
data: {
...initialState
}
data: initialState
});
try {
@@ -125,24 +111,7 @@ class AppContainer extends Component {
return (
<ApolloProvider client={client}>
<Query query={GET_CURRENT_USER}>
{({ loading, error, data: { currentUser } }) => {
if (loading) return <Spin />;
if (error) return error.message;
return (
<Mutation mutation={SET_CURRENT_USER}>
{setCurrentUser => (
<App
currentUser={currentUser}
setCurrentUser={user => {
setCurrentUser({ variables: { user } });
}}
/>
)}
</Mutation>
);
}}
</Query>
<App />
</ApolloProvider>
);
}

View File

@@ -1,4 +1,5 @@
import React from "react";
import React, { useEffect } from "react";
import { useApolloClient, useQuery } from "@apollo/react-hooks";
import { Switch, Route, Redirect } from "react-router-dom";
import firebase from "../firebase/firebase.utils";
@@ -6,32 +7,33 @@ import "./App.css";
//Component Imports
import LandingPage from "../pages/landing/landing.page";
import Manage from "../pages/manage/manage.page";
import ManagePage from "../pages/manage/manage.page";
import PrivateRoute from "../utils/private-route";
import SignInPage from "../pages/sign-in/sign-in.page";
import Unauthorized from "../pages/unauthorized/unauthorized.component";
import { auth } from "../firebase/firebase.utils";
class App extends React.Component {
unsubscribeFromAuth = null;
import { GET_CURRENT_USER } from "../graphql/local.queries";
import LoadingSpinner from "../components/loading-spinner/loading-spinner.component";
import AlertComponent from "../components/alert/alert.component";
import SignOut from "../components/sign-out/sign-out.component";
componentDidMount() {
const { setCurrentUser } = this.props;
console.log("DIDMOUNT");
this.unsubscribeFromAuth = auth.onAuthStateChanged(async user => {
console.log("Current User:", user);
import { UPSERT_USER } from "../graphql/user.queries";
export default () => {
const apolloClient = useApolloClient();
useEffect(() => {
//Run the auth code only on the first render.
const unsubscribeFromAuth = auth.onAuthStateChanged(async user => {
if (user) {
const token = await user.getIdToken();
let token;
token = await user.getIdToken();
const idTokenResult = await user.getIdTokenResult();
const hasuraClaim =
idTokenResult.claims["https://hasura.io/jwt/claims"];
if (hasuraClaim) {
setCurrentUser({
email: user.email,
displayName: user.displayName,
token
});
} else {
// Check if refresh is required.
const metadataRef = firebase
@@ -39,62 +41,71 @@ class App extends React.Component {
.ref("metadata/" + user.uid + "/refreshTime");
metadataRef.on("value", async () => {
// Force refresh to pick up the latest custom claims changes.
const token = await user.getIdToken(true);
setCurrentUser({
email: user.email,
displayName: user.displayName,
token
});
token = await user.getIdToken(true);
});
}
// console.log('###Debug (app.js)| Token', token)
apolloClient.writeData({
data: {
currentUser: {
email: user.email,
displayName: user.displayName,
token,
uid: user.uid,
photoUrl: user.photoURL,
__typename: "currentUser"
}
}
});
//add the bearer token to the headers.
localStorage.setItem("token", token);
apolloClient
.mutate({
mutation: UPSERT_USER,
variables: { authEmail: user.email, authToken: user.uid }
})
.then(r => console.log("Successful Upsert", r))
.catch(error => {
console.log("Upsert error!!!!", error);
});
} else {
setCurrentUser({
email: null,
displayName: null,
token: null
});
apolloClient.writeData({ data: { currentUser: null } });
localStorage.removeItem("token");
}
});
}
componentWillUnmount() {
this.unsubscribeFromAuth();
}
return function cleanup() {
unsubscribeFromAuth();
};
}, [apolloClient]);
render() {
console.log(
"###Debug (App.js) | Props Current User: ",
this.props.currentUser.email
);
return (
<div>
<Switch>
<Route exact path="/" component={LandingPage} />
<Route exact path="/unauthorized" component={Unauthorized} />
<Route
exact
path="/signin"
render={() =>
this.props.currentUser.email != null ? (
<Redirect to="/manage" />
) : (
<SignInPage />
)
}
/>
<PrivateRoute
isAuthorized={this.props.currentUser.email != null}
path="/manage"
component={Manage}
/>
</Switch>
</div>
);
}
}
export default App;
const HookCurrentUser = useQuery(GET_CURRENT_USER);
if (HookCurrentUser.loading) return <LoadingSpinner />;
if (HookCurrentUser.error)
return <AlertComponent message={HookCurrentUser.error.message} />;
return (
<div>
<SignOut />
<Switch>
<Route exact path="/" component={LandingPage} />
<Route exact path="/unauthorized" component={Unauthorized} />
<Route
exact
path="/signin"
render={() =>
HookCurrentUser.data.currentUser ? (
<Redirect to="/manage" />
) : (
<SignInPage />
)
}
/>
<PrivateRoute
isAuthorized={HookCurrentUser.data.currentUser ? true : false}
path="/manage"
component={ManagePage}
/>
</Switch>
</div>
);
};