admin管理员组文章数量:1426620
When I navigate between pages in my React app, a see a bounce at each page (meaning that page is rendered first without any data [e.g. username, date of birth, images], then few milliseconds/seconds later some details appear on the screen as the API request has finished and updated the state.
For example I have the following pages:
<div className="home" onClick={() => history.push('/')}></div>
<div className="user" onClick={() => history.push('/user')}></div>
<div className="settings" onClick={() => history.push('/settings')}></div>
This results in behavior that when I click 'settings' button I first go to /settings
route and then ponents starts rerendering and bouncing while making API requests. In each of these pages I make one or multiple API requests to get data. I make these requests using useEffect
hook. For example:
const Settings = () => {
const [userDetails, setUserDetails] = useState(null);
const [userImages, setUserImages] = useState([]);
useEffect(() => {
const getUserDetails = async () => {
const response = await getUserSettingsDetails();
setUserDetails(response.data);
}
const getUserImages = async = () => {
const response = await getUserSettingsImages();
setUserImages(response.data);
}
getUserDetails();
getUserImages();
}, []);
return (
...
);
}
What I want to achieve:
I want that when I am for example on 'homepage', and click to go to 'settings', to navigate and render Settings page only after the API requests finished and I can have all details on the screen immediately. I have a nice line loading ponent that I want to display in header while loading. (Similar to what YouTube has, it displays a red progress bar when navigating). I also use Redux for this project and I think it could be used here but I do not understand how to do this. Could anyone please explain how to achieve such behavior.
When I navigate between pages in my React app, a see a bounce at each page (meaning that page is rendered first without any data [e.g. username, date of birth, images], then few milliseconds/seconds later some details appear on the screen as the API request has finished and updated the state.
For example I have the following pages:
<div className="home" onClick={() => history.push('/')}></div>
<div className="user" onClick={() => history.push('/user')}></div>
<div className="settings" onClick={() => history.push('/settings')}></div>
This results in behavior that when I click 'settings' button I first go to /settings
route and then ponents starts rerendering and bouncing while making API requests. In each of these pages I make one or multiple API requests to get data. I make these requests using useEffect
hook. For example:
const Settings = () => {
const [userDetails, setUserDetails] = useState(null);
const [userImages, setUserImages] = useState([]);
useEffect(() => {
const getUserDetails = async () => {
const response = await getUserSettingsDetails();
setUserDetails(response.data);
}
const getUserImages = async = () => {
const response = await getUserSettingsImages();
setUserImages(response.data);
}
getUserDetails();
getUserImages();
}, []);
return (
...
);
}
What I want to achieve:
I want that when I am for example on 'homepage', and click to go to 'settings', to navigate and render Settings page only after the API requests finished and I can have all details on the screen immediately. I have a nice line loading ponent that I want to display in header while loading. (Similar to what YouTube has, it displays a red progress bar when navigating). I also use Redux for this project and I think it could be used here but I do not understand how to do this. Could anyone please explain how to achieve such behavior.
Share Improve this question edited Apr 26, 2021 at 22:27 user12051965 asked Apr 26, 2021 at 22:18 user12051965user12051965 15712 silver badges39 bronze badges3 Answers
Reset to default 2You can create an extra state called isLoading
and set it true when any fetch of data starts. Then, below the await statement, you can set isLoading
to false.
So, with this, you can use the isLoading
state in your JSX code, to make a conditional rendering, for example, you can display a Loading Component while the isLoading
variable has the value of true, then, when the variable is false, display your page as you want.
const Settings = () => {
const [state, setState] = useState({});
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
const getAllInformation = async () => {
// start loading
setIsLoading(true);
// make the request here
const data = await fetch();
setState({ ...data });
// already finished here
setIsLoading(false);
};
getAllInformation()
}, []);
return (
<div>
{isLoading ? (
<Loading />
) : (
{
/* MORE CODE */
}
)}
</div>
);
};
hi I think you can use Promise.all([]) and a loading state
const Settings = () => {
const [userDetails, setUserDetails] = useState(null);
const [userImages, setUserImages] = useState([]);
const [loading,setLoading] = useState(false)
const getUsersInfos = async () => {
try {
const result = await new Promise.all([
getUserSettingsDetails(),
getUserSettingsImages(),
])
const details = result[0]
const images = result[1]
//i'm not sure if we need to test
if(details.data && images.data){
setUserDetails(details.data);
setUserImages(images.data);
setLoading(true)
}
} catch (error) {
console.log(error);
}
}
useEffect(() => {
getUsersInfos();
}, []);
return (
<>
{loading && (
...
)}
</>
);
}
Although I believe @Daphaz answer is pretty well, I'll go with a better and cleaner approach using redux-thunk or redux-sagas. With redux you can only do simple synchronous updates, and here you will be doing asynchronous updates hence you will need a middleware like those I mentioned.
Redux-thunk Redux-sagas
There are tons of examples of usings this middlewares to achieve exactly what you are looking for.
本文标签: javascriptReact render page after API callStack Overflow
版权声明:本文标题:javascript - React render page after API call - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745480082a2660136.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论