Login Pending State
I think that a selector is fine, but you need to have additional information in your store that tells you whether or not someone is currently logging in.
At some point in your app you are calling a sign-in method which is an async
function that takes time to execute. I'm not sure if you are await
-ing the result or not.
Eventually the internal state of auth
will change and the onAuthStateChanged
callback from your useEffect
will dispatch
the user object to the store.
I propose an additional dispatch
that sends some sort of PENDING_LOGIN
action to your store at the very beginning of the login. Somewhere in your store you can save either a boolean
isLoggingIn
or an enum
loginState
.
You would change your login handler:
const handleLogin = async () => {
// immediately dispatch the pending login
dispatch({type: "PENDING_LOGIN" });
const {user} = await await auth.signInAnonymously();
// could dispatch `setUser` action from here instead of from `useEffect`, if you want to
}
In your Dashboard
component, you can access this new information from your store.
const Dashboard = () => {
const user = useSelector(userInfo);
const isLoggingIn = useSelector(someSelector);
if ( ! user && ! isLoggingIn ) {
window.location.href = "/";
}
return (
<Section>
<Container>
<h1>Dashboard</h1>
{user
? <p>If you can see this then you are logged in</p>
: <p>Logging in...</p>
}
</Container>
</Section>
)
};
window.location
Changing window.location
does actually add the URL to history. Here's some info from MDN.
Regarding setting a string value to window.location
:
Whenever a new value is assigned to the location object, a document will be loaded using the URL as if location.assign() had been called with the modified URL.
Regarding this assign()
method:
The Location.assign() method causes the window to load and display the document at the URL specified. After the navigation occurs, the user can navigate back to the page that called Location.assign() by pressing the "back" button.
If you want to navigate to a page without adding it to history, there is a separate method for that.
The replace() method of the Location interface replaces the current resource with the one at the provided URL. The difference from the assign() method is that after using replace() the current page will not be saved in session History, meaning the user won't be able to use the back button to navigate to it.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…