Reputation: 5039
I have this code:
function App() {
const { setUser } = useContext(UserContext);
firebase.auth().onAuthStateChanged((user) => {
console.log("test");
if (user) {
console.log("user");
setUser({ id: user.uid, email: "" });
} else {
console.log("null");
setUser(null);
}
});
return (
<Container>
<Router />
</Container>
);
}
userContext:
const initialState = {
email: null,
id: null,
};
export interface IUserContext {
user: IUser | null;
setUser: React.Dispatch<IUser | null>;
}
export const UserContext = createContext<IUserContext>({
user: initialState,
setUser: () => {},
});
interface IUserContextProvider {
children: JSX.Element;
}
export function UserContextProvider({ children }: IUserContextProvider) {
const [user, setUser] = useState<IUser | null>(initialState);
return (
<UserContext.Provider value={{ user, setUser }}>
{children}
</UserContext.Provider>
);
}
I am trying to set a user object on log in, or log out. The problem is this keeps looping infinitely. How do I stop this from happening? I essentially just want to know when someone is logged in, or logged out.
Upvotes: 1
Views: 552
Reputation: 8308
This can be the responsibility of your Provider itself and run inside it's useEffect
like so :-
export function UserContextProvider({ children }: IUserContextProvider) {
const [user, setUser] = useState<IUser | null>(initialState);
useEffect(()=>{
const unsubscribe = firebase.auth().onAuthStateChanged((user) => {
console.log("test");
if (user) {
console.log("user");
setUser({ id: user.uid, email: "" });
} else {
console.log("null");
setUser(null);
}
});
return unsubscribe;
},[])
return (
<UserContext.Provider value={{ user, setUser }}>
{children}
</UserContext.Provider>
);
}
The onAuthStateChanged
only needs to be registered one-time and so []
dependency array useEffect
is the right place for it. The unsubscribe
will only work when this component unmounts which won't happen for you unless you exit the website.
Upvotes: 2