I want to prevent my app from displaying the wrong case of a conditional rendering (before retrieving the data) during the loading phase.
Let me explain, when I'm logged in (the user data is stored via useContext hook) and I refresh my page: automatically the page displays the forms for log in but it disappears a second after that my PWA understands that I'm logged in as it retrieves the user data. How can I prevent that little timing issue ?
Thank you
It should actually be quite easy to keep from rendering it, until you know for sure that it needs to be shown. Something like this:
{this.state.needToShowLogin &&
<LoginForm />
}
In the init part (e.g. class constructor) you start with this value being false. Then change it if & when you decide that it needs to be set to true.
Related
I have a React application with a loading spinner that goes away when an API call finishes. I have the loading spinner set up to render in my index file like this:
if (isFinishedLoading === false) {
return (
<LoadingSpinner/>
);
}
return (
{rest of code}
)
Where isFinishedLoading is false as set by useState. I call the needed API like this in useEffect:
useEffect(() => {
apiGET()
}, [])
and I call setIsFinishedLoading(true) inside of apiGET().
However, there is always a split second where the page is not fully rendered, it looks like some divs appear before others and the site flickers a little bit, it doesn't look like a fully rendered site.
My question is: is this just a fact of using React that it will take a half second for the page to fully render? Or am I implementing my loading spinner in the wrong way?
I've tried a few things:
Putting my setIsFinishedLoading(true) in a setTimeout(),
Adding an additional loading flag to wait until all images are loaded like this: React: Show loading spinner while images load
Ideally, I'd be able to call something like img "onLoad" for divs, but that sounds a lot like useEffect() anyway. For what it's worth, the application is in Gatsby.
Because of some of your Dom need the data whose got in async HTTP apiGet. They will appear later than other Dom whose not need api.
If you want to show both of them at the same time ,you may need to promote your Loading and state to a parent's component to control all Dom's display while data is got from apiGet .
I am working on a React Native project, and I am currently focused in the Chatroom aspect. Due to user roles, this component is embedded in another component for 2 of the 3 user types, but navigated to (not embedded in anything other than App.js) for the other type.
This means sometimes the app uses the props it was supplied with, and other times it uses the props.route.params?.item syntax to extract information. As is such its difficult to maneuver with useEffects to make sure it works on both sides.
The issue I am facing is with the embedded version of this component. It takes three props, the chatroom, and two booleans that are unrelated to this. The chatroom can change as a GUARDIAN user can see their CHILD user's messages, but they cannot text in them (those are the other two boolean values). From the parent component, users can toggle whether they are the Guardian accessing their own chat, or if they want to view their children' chats. While the all three values change properly (I console.log'd this in the parent component to confirm) the chatroom does not change inside of the embedded component.
I will show you what I mean...
// PARENT COMPONENT //
function renderMessageThread(chat){
console.log("\n\n\n", chat[0].messages.length, "LANDING")
console.log(msgUser.id, isThisChatMine())
return <MessageThread hardCodedChat={chat} hardCoderUserId={msgUser.id} isItMe={isThisChatMine()} />
}
The console.logs show the proper values. Inside the MessageThread component, both hardCoderUserId and isItMe are correct values, even when isItMe changes values. hardCodedChat, however, never has its value changed from the first time it is created. Does anyone have any ideas on how to have this changes as well?
I have a React application. I am on a particular page which has a form. I enter details. If I resize the window to mobile view, the page is getting re-rendered because of which the form is becoming empty. Why?
My guess is that some state variable is getting changed while resizing because of which the page is getting rendered again. So, I removed all the state variables of the page and kept a simple
return (
<H1>Hello!</H1
)
in the render function. And I still see that the page is getting re-rendered. (I checked it on the
useEffect(()=>{
alert('rendered!!!')
},[])
Now, I am not sure if that is the reason why the page is getting re-rendered or something else. Any pointers on why this is happening? If it has to be any state change, how to track which part of the state is getting changed?
What do I need:
I want to display a loading indicator, when user navigates between pages. I saw an example https://github.com/zeit/next.js/tree/canary/examples/with-loading and it works for me.
In my app I've implemented a similar logic. For an experiment as a loading indicator I just change the color of tag .
try {
if (isLoading) {
document.getElementsByTagName('body')[0].style.backgroundColor = 'red'
console.log('RED')
}
else {
document.getElementsByTagName('body')[0].style.backgroundColor = 'green'
console.log('GREEN')
}
}
catch (err) {
}
And I use events like this:
Router.events.on('routeChangeStart', url => {
setIsLoading(true)
})
Router.events.on('routeChangeComplete', () => setIsLoading(false))
Router.events.on('routeChangeError', () => setIsLoading(false))
What happens:
In a first time, when page is not built yet and not loaded from the server, and user navigates to it, the color is changed and all is fine. But after, when user comes back to the already loaded page, the color of body is not updated.
This code is performed in any case, because I see console.log, but color is not changes.
Interesting thing #1 - if I put 'debugger' before the line of changing the color, then it stops on this line and color updated, even for already loaded pages. As I need.
Interesting thing #2 - If I will use setTimeout for coloring by green, then for already loaded pages, the background will stay green during redirection. After the redirection will be finished, it will became red, and after the timeout it will be again green.
I use:
nextjs 9.1.7
React 16.12.0
Also redux, but I dont think it's important.
It looks like browser does not update DOM while navigation to the already loaded page is performing.
Can anyone give me an advice, what could the reason that for already loaded pages I cannot update DOM when user does navigation?
I found a reason of a problem.
How does it work:
Actually, when page is already rendered and loaded by nextjs, the router renders it immediately after the user navigates on it.
Why the problem did happen:
In my example I had two pages. They contained a lot of data (one of them was especially heavy). After the user navigated to the already loaded page, the browser has started the rendering immediately and it took ~2 seconds. Since the rendering in browser was in progress, it was not able to render the loading indicator. And after the rendering was done, the event "routeChangeComplete" was fired and the loading indicator disappeared immediately after the page was loaded.
What to do:
More correct to refactor the page and make it render faster. Then we don't need loading indicator for the render.
A workaround could be the next - when you want to do a redirect, you need to render the loading indicator first. And only after, start the redirection and therefore a render of the page. The simpliest way, just to test it is use a setTimeout, to delay the redirection.
But I do not recommend this way.
P.S. an example in sandbox worked well because pages there a very lightweight, and long loading was emulated through setTimeout which does not block rendering.
I have a router with a lot of screens and nested navigators, and everything is working exactly how I want it to. I'm using redux for a lot of state throughout, but I'm not using redux for navigation state.
If something unexpected goes wrong, for example no network connection, an alert comes up. Once the alert is dismissed, there may be some missing information on the screen. I did the "pull down to refresh" thing using RefreshControl and StackActions.reset in a couple of the most common places with ScrollViews.
I suppose it's possible to write this refresh function for every single screen to re-fetch data on pull-down refresh, but it seems wrong, like I should be able to get the navigation state from anywhere and then use StackActions.reset to reset the navigation state to exactly where it was where the actions are navigations to everything in the stack using a generic refresh function. Having a bit of trouble deciphering the navigation state to be able to do this generically from anywhere though, has anyone else done something similar?
try
navigation.replace(routeName)