I looked at what nextjs returns when navigating the page and noticed that the state of hydration is duplicated on the page and transmitted in two different properties of the object:
I do not understand whether this is the norm of logic or whether it is not a duplication of logic.
I use next-i18next for multilingualism and next-redux-wrapper for hydration of redux storage on the server, and this is exactly the state it creates and is located in these two properties.
Therefore, when I noticed this, I wondered if this was normal logic, since my storage is not so small, and I would not like any extra operations when working on the server.
If you need more information, write in the comments.
It looks like the two set of props- pageProps and props are related to the loading of the Custom App component and the page component respectively. You can read about Custom App component here
And as the doc states.
pageProps is an object with the initial props that were preloaded for
your page by one of our data fetching methods, otherwise it's an empty
object.
Related
I'm using next-i18next to translate my Next.js pages. I'm wondering if using
const { t } = useTranslation('common') everywhere for each react component would have a negative impact on performance. The alternative would be calling it in the parent and passing it down to the children which IMO is not a smart solution since it add an extra prop to each component.
It is the way to do it.
The alternative as you describe it, passing the function itself as a prop, is essentially the same thing. It would just point to a reference of the original function.
But, passing it as a prop would likely add more overhead to react internally as the rendering process would need to find out if that prop changed, on every component it passes through.
Using t() as destructured from a hook, you would just call a reference to the function, nothing more.
I have a MERN app in which I have integrated NextJS. First time with NextJS so bear with me. I have initially used SSR everywhere (getServerSideProps).
Key points:
I have over 150,000 pages with static content that it's never going to change.
Every week I add around +100 new pages.
I guess the ideal situation here would be using getStaticProps and getStaticPaths and, after an initial build of those 150k pages, just build the new added pages every week and keep what I already have built as it is since it's never going to change.
How can I achieve this? Should I use revalidate here? I have been reading about it in the documentation but I don't completely understand it.
That can be achieved with getStaticProps/getStaticPaths. You'll have to use fallback: true or fallback: 'blocking' in getStaticPaths.
With fallback: true the paths not generated at build time will serve a fallback page on the first request while Next.js statically generates the page. When this is done the page will be swapped from the fallback page to the actual full page.
With fallback: 'blocking', the paths not generated at build time will wait for the HTML to be generated by Next.js, then serve the page once that's done. Unlike fallback: true, since there's no fallback the rendering gets blocked until the page is generated, similar to what happens during server-side rendering.
In both cases the page gets added to the list of pre-rendered pages. Subsequent requests to the same path will serve the pre-generated page.
Neither of these options is supported by next export, in case you depend on that.
Note that revalidate is used in getStaticProps for Incremental Static Regeneration - in cases where you'd want to update existing, generated pages. Since you mentioned generated pages will never change, then there's no need to use revalidate.
I'm using Gatsby for the first time on a simple website project. I'm accustomed with traditional React apps where there is a root file component, typically "App.js" that one attaches Providers and other global level functionality.
Gatsby doesn't offer a root App.js, but it does offer wrapRootElement and wrapPageElement, which, after a bit of wrangling, worked just fine on my localhost.
export const wrapRootElement = ({ element }) => {
return (
<ThemeProvider theme={theme}>
{element}
</ThemeProvider>
)
}
and
export const wrapPageElement = ({ element, props }) => {
return <Layout {...props}>{element}</Layout>
}
inside of gatsby-browser.js (and with appropriate local imports and such)
(using Root for my Theme Provider and Page for my Layout wrapper, which includes header and footer elements)
I used 'gatsby clean' then 'gatsby build' to generate the deployable public folder, but upon upload to my shared host, only the inner portion showed up, not the header or footer, nor did my theme colors show up.
On a whim, I downloaded Gatsby and pulled out their "using-redux" example, built, and deployed it to the same shared host with similar results — that is, it doesn't behave as expected.
What am I missing? Since it fails on the Gatsby example, I'm presuming it as something to do with my server side setup (recall, it works fine on localhost). I have Node installed, but I'm not using it as part of this app; it's intended to be completely static and I'm just trying to use the wrappers to clean up my code.
After toying around with it some more, I replicated the code in gatsby-browser.js into gatsby-ssr.js. Voila, it worked.
This article is what inspired me, sort of: https://www.gatsbyjs.org/docs/api-files-gatsby-browser/. It states:
If you use one of them, consider if you should implement it in both
gatsby-ssr.js and gatsby-browser.js.
I had read the article earlier, but didn't take the gatsby-ssr.js file as being a requirement. Apparently, I should have interpreted the word "should" a bit more forcefully.
The problem is about how to maintain the content and state of an iframe in a component of Vue no matter the component is showing or hiding.
I tried two methods:
(1) using keep-alive together with vue-router
<keep-alive>
<router-view>
<Component></Component>
</router-view>
</keep-alive>
(2) take it as a sub component, using v-if to show and hide instead of vue-router
<Component v-if="$store.state.isShow"></Component>
both methods keeps the content of component but the iframe still refreshes every time, so is there any method to achieve just hiding and showing the iframe?
A similar question is Thomas question, he also uses the vue-router method and does not work out, I agree with the opnion of Thomas that Vue just keeps the content of component but not of iframe.
Thanks a lot!
If the sub component approach works for you:
<Component v-if="$store.state.isShow"></Component>
then a slight modification will keep the iframe from being refreshed on state changes:
<Component v-show="$store.state.isShow"></Component>
Note that this only works if the route remains unchanged.
If you actually need to use different routes, and if the only problem with refreshing the iframe is performance, you might be able to get away with loading the iframe contents via ajax and caching it in local storage.
I still can't quite get Meteor's load order fully under control. I use a lot of 3rd-party scripts when using Bootstrap templates with animations and a lot of these scripts break because they are created with the traditional load order in mind for DOM nodes.
Meteor does not follow this traditional load order, so a lot of times DOM nodes aren't ready when the scripts fire.
I made a simple Meteor app that console logs a message each time a script inside of a particular folder or template.rendered callback is loaded.
https://github.com/fuzzybabybunny/meteor-load-order-test
You can see it deployed here (open up Chrome Console)
http://load-order-test.meteor.com/
There are a few strange things going on.
main.js and main.html are actually loaded very soon, counter to what the documentation says: http://docs.meteor.com/#/full/structuringyourapp
all the DOM nodes are actually created earlier than expected
with six templates that still have yet to have their .rendered() callbacks fired, the max number of DOM nodes has already been reached. We should expect more DOM nodes to be added with each .rendered() callback being fired.
Can someone help explain why I'm seeing these strange things?
Also, is there a surefire way to only run a script once all DOM nodes have been created? Currently it seems like using jQuery to append <script> tags somewhere on the DOM inside of Template.Layout.rendered would be the most foolproof.
Template.Layout.rendered = function(){
console.log('layout template rendered and the number of DOM nodes is ' + document.getElementsByTagName('*').length);
$('head').append('<script src="/javascript/domCompleteScript.js"></script>');
};
Per the documentation, slightly further down the page:
client/lib/ # code for the client to be loaded first
This folder is for compatibility JavaScript libraries that rely on variables declared with var at the top level being exported as globals. Files in this directory are executed without being wrapped in a new variable scope. These files are executed before other client-side JavaScript files.
I would try putting the 3rd-party scripts into the following places, just to see what works best:
client/lib
client/compatibility
lib