Reputation: 39
please help. I can't make the loading appear correctly. So whenever the user click Login or Logout, it should be Loading... first for 2 second, and then show the result whether the user is Login or not. Instead, my current result is it always loading and never ends.
Here's my code:
import React, { useState } from "react";
import "./App.css";
const App = () => {
const [state, setState] = useState({
user: "John Doe",
isLogin: false,
isLoading: false,
});
const handleClick = () => {
setTimeout(() => {
setState({
isLoading: !state?.isLoading,
user: state?.user,
status: !state?.status,
isLogin: !state?.isLogin,
});
}, 2000);
};
return (
<>
<div className="App">
<h1>Practice makes perfect</h1>
{state?.isLoading ? (
<p>Loading...</p>
) : (
<button onClick={() => handleClick()}>
{state?.isLogin ? "Logout" : "Login"}
</button>
)}
<p>{state?.isLogin ? `Hello ${state?.user}` : "Please Login"}</p>
</div>
</>
);
};
export default App;
Thank you, sorry for bad english.
Upvotes: 0
Views: 1384
Reputation: 304
You need a handler to change your isLoading state when user clicked on the button. So this code is what you need:
import React, { useState } from "react";
import "./App.css";
const App = () => {
const [state, setState] = useState({
user: "John Doe",
isLogin: false,
isLoading: false,
});
const handleLoading = () => {
setTimeout(() => {
setState({
...state,
isLoading: false,
isLogin: !state?.isLogin,
});
}, 2000);
};
const handleClick = () => {
setTimeout(() => {
setState({
...state,
isLoading: !state?.isLoading,
user: state?.user,
status: !state?.status,
isLogin: !state?.isLogin,
});
handleLoading();
}, 2000);
};
return (
<>
<div className="App">
<h1>Practice makes perfect</h1>
{state?.isLoading ? (
<p>Loading...</p>
) : (
<button onClick={() => handleClick()}>
{state?.isLogin ? "Logout" : "Login"}
</button>
)}
<p>{state?.isLogin ? `Hello ${state?.user}` : "Please Login"}</p>
</div>
</>
);
};
export default App;
Upvotes: 1
Reputation: 25415
You could do it like this... your example is simple enough that you can do it this way and maybe you wouldn't want to do this in a "real" app, but first calling setState
with your loading state, followed by an async call (here using setTimeout
) to get your logged-in user info should work ok:
const handleClick = () => {
// Loading here while we wait for the setTimeout to kick off.
setState({
isLoading: true,
user: undefined,
status: "Loading",
isLogin: false
});
setTimeout(() => {
// Assume success here
setState({
isLoading: false,
user: "Logged-in Username",
status: "success",
isLogin: true
});
}, 2000);
};
Here's a codesandbox where this is running. https://codesandbox.io/s/ecstatic-poincare-2jpio?file=/src/App.js
Upvotes: 1