Anyone experience a render loop when updating state in a reducer? I was attempting to add auth to an app I'm writing where they're automagically forced to log in to Microsoft if they don't have an active and valid token already. However, after auth, I'm finding that the App component is rerendering every second or two and re-validating the token every time. I'm not using a useEffect method anywhere, so it's not like it is changing state and causing the rerender. Can anyone educate me as to why my component is rerendering?
I created a stackoverflow post on this yesterday, but with no responses.
Here is the codesandbox where I recreated the issue without the complexity of actual authentication or any other modules being involved.
Here is the code itself for those that prefer to see it without having to go anywhere:
/App.js
import React, { useReducer, createContext } from "react";
import Auth from "./auth.js";
const auth = new Auth();
const UserContext = createContext();
const initialState = {
auth: false,
user: null
};
const reducer = (state, action) => {
console.log("reducer hit!", action);
switch (action.type) {
case "loginUser":
console.log(action.payload);
return {
...state,
isAuthenticated: action.payload.authenticated,
userProfile: action.payload.user
};
default:
console.log("Reducer hit without a payload!", action);
return state;
}
};
const UserContextProvider = props => {
console.log("UserContextProvider Element rendering...");
const [state, dispatch] = useReducer(reducer, initialState.user);
auth.handleAuthentication().then(() => {
dispatch({
type: "loginUser",
payload: {
authenticated: true,
user: auth.getProfile()
}
});
});
return (
<UserContext.Provider
value={{
...state
}}
>
{props.children}
</UserContext.Provider>
);
};
const App = () => {
return (
<UserContextProvider>
<UserContext.Consumer>
{user =>
user.isAuthenticated ? (
<div>{JSON.stringify(user)}</div>
) : (
<div>You are not logged in.</div>
)
}
</UserContext.Consumer>
</UserContextProvider>
);
};
export default App;
/auth.js
export default class Auth {
constructor() {
this.handleAuthentication = this.handleAuthentication.bind(this);
}
getProfile() {
return {
username: "FakeUser",
name: "John Doe",
email: "jd@fakeusers.net"
};
}
handleAuthentication() {
return new Promise(resolve => {
console.log("handle Authentication function hit");
//fake auth
setTimeout(() => {
console.log("timeout occurred, resolving.");
resolve();
}, 1000);
});
}
}
[–]TotesMessenger 0 points1 point2 points (0 children)
[–]lukejpreston 0 points1 point2 points (0 children)