eiv*_*dml 37 fetch reactjs redux next.js sanity
我正在寻找在 Next.js 应用程序中更好地获取数据的解决方案。在这个问题上我不只是在寻找一个解决方案,我正在寻找多种选择,所以我们可以看一下利弊。
现在我有几个页面都包含一个显示一些静态内容的组件和一个从 API 获取的一些动态内容的组件。每个页面都做一个fetch()
在他们getInitialProps()
自己的页面数据中,还有页脚数据,这对所有页面都是一样的。
这当然有效,但有很多重复的数据提取。页脚数据将始终为所有页面显示并且始终相同。它也很少在 API 中更改,因此无需重新验证数据。
我不只是想解决这个问题,我也在寻找一个概述,以便为未来的项目学习一些新的实践。我喜欢编写“明显”的代码,所以不要寻找太hacky的解决方案,比如写入window
对象等。优先考虑依赖较少的简单解决方案。目标是一个快速的网站。减少网络使用/API 调用并不是那么重要。
这是我想出的可能的解决方案,从简单/明显到更复杂。
getInitialProps()
添加到 props,因此数据可用于所有页面所有这些“工作”,但其中大多数会不必要地重新获取数据,和/或增加一点复杂性。以下是我所看到的优缺点(数字与上面相同):
getInitialProps()
.fetch()
依次进行两次调用(首先在 _app.js 中加载页脚内容,然后在每个页面中获取自定义内容),所以它甚至更慢。rel="preload"
预取技术不会与所有类型的获取(使用groq例如理智的客户)的工作。要对数据进行页面加载完成后加载没有“跳跃”的内容,我们应该提供useSWR()
具有initialData
仍需要我们在获取数据getInitialProps()
,但它是不够的,只是做在服务器端。可以用新的getServerSideProps()
。当前解决方案,使用项目符号 2 中描述的解决方案。
const HomePage = (props) => {
return (
<Layout data={props.footer}>
<Home data={props.page} />
</Layout>
)
}
// Not actual query, just sample
const query = `{
"page": *[_type == "page"][0],
"footer": *[_type == "footer"][0]
}`
HomePage.getInitialProps = async () => {
const data = await client.fetch(query)
return {
page: data.page
footer: data.footer
}
}
export default HomePage
Run Code Online (Sandbox Code Playgroud)
希望对此有更多的了解。我缺少一些明显的东西?
Hoo*_*man 23
O'right! I found this thread while I was looking for something else. But since I had to work on similar issues, I can give you some directions, and I will do my best to make it clear for you.
So there are some data which you want to have it share, across your app (pages/components).
_app.js
file in root of pages
directory. For more information follow this link: https://nextjs.org/docs/advanced-features/custom-appgetInitialProps
in your pages to fetch data from your API, you can also use the same method in _app.js
. So, I would fetch those data which I need to share them across my app and eliminate my API calls.Well, Now I can think of two ways to share the data across my app
createContext
hooks.1.1. Create a DataContext using createContext hooks. and wrap <Component {...pageProps} />
with your <DataContext.Provider>
.
Here is a code snippet to give you a better clue:
<DataContext.Provider value={{ userData, footerData, etc... }}>
<Component {...pageProps} />
</DataContext.Provider>
Run Code Online (Sandbox Code Playgroud)
1.2. Now in other pages/components you can access to your DataContext like following:
const { footerData } = useContext(DataContext);
Run Code Online (Sandbox Code Playgroud)
And then you are able to do the manipulation in your front-end
props
using getInitialProps
2.1. getInitialProps
is used to asynchronously fetch some data, which then populates props
. that would be the same case in _app.js
.
The code in your _app.js
would be something like this:
function MyApp({ Component, pageProps, footerData }) {
//do other stuffs
return (
<Component {...pageProps} footerData={footerData} />
;
}
MyApp.getInitialProps = async ({ Component, ctx }) => {
const footerRes = await fetch('http://API_URL');
const footerData = await footerRes.json();
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx);
}
return { pageProps, footerData };
};
Run Code Online (Sandbox Code Playgroud)
2.2. Now in your pages (not in your components) you can access to props including those you have shared from _app.js
and you can start to do you manipulation.
Hope I could give you a clue and direction. Have fun exploring.
归档时间: |
|
查看次数: |
18426 次 |
最近记录: |