-
-
Notifications
You must be signed in to change notification settings - Fork 265
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use useMemo for hydration and avoid unnecessary hydrates (#510)
* Use useMemo for hydration and avoid unnecessary hydrates (#502) * Upgrade packages and refactor a bit * Added necessary testing dependency * Stop hydrating on server and use useLayoutEffect for client hydration * Added pokemon page with rtk's createApi * Added back dispatch in GSP in demo repo * A change in query params constitutes a new page now * Improve performance by using another hook on server * Add detail page * New approach: split gsp and gssp and hydrate based on those * Added a second type of initial state handling with more explanations * Improved useMemo comment * Make sure hydrates work when staying on the same page * Add links to demo repo to test issue (seems like no issue) * Proper gipp fix (#512) * ESLint fix * Gipp testcase and example page in RTK repo (#514) * Add GIP to _app and add GIP in page to RTK repo * Added e2e test for RTK repo * Added testcase for GIAP and GIPP to wrapper * Consistent casing and formatting in comments Fix #493 #495 #496 Co-authored-by: voinik <[email protected]>
- Loading branch information
1 parent
cd34b26
commit 8e098f7
Showing
33 changed files
with
16,364 additions
and
11,395 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
nodeLinker: node-modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,39 @@ | ||
import React, {FC} from 'react'; | ||
import React from 'react'; | ||
import {Provider} from 'react-redux'; | ||
import {AppProps} from 'next/app'; | ||
import {wrapper} from '../store'; | ||
import App, {AppProps} from 'next/app'; | ||
import {fetchSystem, wrapper} from '../store'; | ||
|
||
const MyApp: FC<AppProps> = ({Component, ...rest}) => { | ||
interface PageProps { | ||
pageProps: { | ||
id: number; | ||
}; | ||
} | ||
|
||
const MyApp = ({Component, ...rest}: Omit<AppProps, 'pageProps'> & PageProps) => { | ||
console.log('rest: ', rest); | ||
const {store, props} = wrapper.useWrappedStore(rest); | ||
|
||
return ( | ||
<Provider store={store}> | ||
<h1>PageProps.id: {rest.pageProps.id}</h1> | ||
<Component {...props.pageProps} /> | ||
</Provider> | ||
); | ||
}; | ||
|
||
MyApp.getInitialProps = wrapper.getInitialAppProps(store => async (appCtx): Promise<PageProps> => { | ||
// You have to do dispatches first, before... | ||
await store.dispatch(fetchSystem()); | ||
|
||
// ...before calling (and awaiting!!!!) the children's getInitialProps | ||
const childrenGip = await App.getInitialProps(appCtx); | ||
return { | ||
pageProps: { | ||
// And you have to spread the children's GIP result into pageProps | ||
...childrenGip.pageProps, | ||
id: 42, | ||
}, | ||
}; | ||
}); | ||
|
||
export default MyApp; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import React from 'react'; | ||
import {useDispatch, useSelector, useStore} from 'react-redux'; | ||
import Link from 'next/link'; | ||
import {InferGetServerSidePropsType, NextPage} from 'next'; | ||
import { | ||
fetchDetail, | ||
selectDetailPageData, | ||
selectDetailPageId, | ||
selectDetailPageStateTimestamp, | ||
selectDetailPageSummary, | ||
selectSystemSource, | ||
wrapper, | ||
} from '../../store'; | ||
|
||
const Page: NextPage<InferGetServerSidePropsType<typeof getServerSideProps>> = ({serverTimestamp}) => { | ||
console.log('State on render', useStore().getState()); | ||
console.log('Timestamp on server: ', serverTimestamp); | ||
const dispatch = useDispatch(); | ||
const pageId = useSelector(selectDetailPageId); | ||
const pageSummary = useSelector(selectDetailPageSummary); | ||
const stateTimestamp = useSelector(selectDetailPageStateTimestamp); | ||
const data = useSelector(selectDetailPageData); | ||
const source = useSelector(selectSystemSource); | ||
|
||
console[pageSummary ? 'info' : 'warn']('Rendered pageName: ', pageSummary); | ||
|
||
if (!pageSummary || !pageId || !data) { | ||
throw new Error('Whoops! We do not have the pageId and pageSummary selector data!'); | ||
} | ||
|
||
return ( | ||
<> | ||
<div style={{backgroundColor: 'pink', padding: '20px'}}>Timestamp on server: {serverTimestamp}</div> | ||
<div style={{backgroundColor: 'lavender', padding: '20px'}}>Timestamp in state: {stateTimestamp}</div> | ||
<div className={`page${pageId}`}> | ||
<h1>System source: {source}</h1> | ||
<h3>{pageSummary}</h3> | ||
<Link href="/subject/1">Go id=1</Link> | ||
| ||
<Link href="/subject/2">Go id=2</Link> | ||
| ||
<Link href="/detail/1">Go to details id=1</Link> | ||
| ||
<Link href="/detail/2">Go to details id=2</Link> | ||
| ||
<Link href="/gipp">Go to gipp page</Link> | ||
| ||
<Link href="/pokemon/pikachu">Go to Pokemon</Link> | ||
| ||
<Link href="/">Go to homepage</Link> | ||
</div> | ||
<button onClick={() => dispatch(fetchDetail(pageId))}>Refresh timestamp</button> | ||
</> | ||
); | ||
}; | ||
|
||
export const getServerSideProps = wrapper.getServerSideProps(store => async ({params}) => { | ||
const id = params?.id; | ||
if (!id || Array.isArray(id)) { | ||
throw new Error('Param id must be a string'); | ||
} | ||
|
||
await store.dispatch(fetchDetail(id)); | ||
|
||
return { | ||
props: { | ||
serverTimestamp: new Date().getTime(), | ||
}, | ||
}; | ||
}); | ||
|
||
export default Page; |
Oops, something went wrong.