使用服务器端渲染获取数据的正确方法(Next.js,何时使用 componentDidMount 以及何时使用 componentWillMount)
Posted
技术标签:
【中文标题】使用服务器端渲染获取数据的正确方法(Next.js,何时使用 componentDidMount 以及何时使用 componentWillMount)【英文标题】:Correct way to fetch data with server side rendering (Next.js, when to use componentDidMount and when to use componentWillMount) 【发布时间】:2019-05-30 01:16:55 【问题描述】:我正在使用 Next.js,在 _app.js 页面(我们在其中设置一般 webapp 状态)我有 2 种类型的数据,我需要在标题中包含(因此对于每个组件)。
1) 第一种类型是标题信息,此信息应在应用加载之前呈现。我将使用 get getInitialProps 调用端点并将它们放入 props 中,然后再到 componentWillMount 中将它们添加到状态中。
2) 第二种类型是 Search 组件的数据,它是很多数据,我不特别介意在应用程序已经呈现时加载它,因为它没有显示在第一个用户视觉中。 所以我猜测这里最好使用 componentDidMount 和 asynchorslly 调用获取 serach 对象数据的端点,而不是使用它添加设置状态。
这个问题的目的是双重的:
1) 回顾 - 我是否正确地考虑了这一点,还是我错过了什么?
2) 问题 - 现在,在第一次渲染后加载数据时,我正在传递数据,如下所示:_app.js -> 布局 -> 菜单 -> SearchBar 所以我的问题是,在我的 searchBar 我需要做类似的事情
componentDidMount()
this.setState( options: this.props.searchBarSource )
但是,因为 _app.js 正在使用异步调用填充此数据,这是否意味着我将始终得到一个空对象? W解决这个问题的正确方法是什么?如果我将TimeOut 设置为大约 3 秒,然后设置数据是正常的解决方案还是非常hacky,还有更好的方法吗?
【问题讨论】:
您可以使用生命周期来检测this.props.searchBarSource
的变化并进行相应的存储。但是你真的需要将 props 同步到 state 吗?您不能在通常使用this.state.options
的地方使用this.props.searchBarSource
吗?
【参考方案1】:
您正在尝试做的事情是有道理的。使用 NextJS,您需要非常谨慎地决定哪些数据应该加载服务器端,哪些不应该。
这里有一些提示:
搜索组件中不需要setState
,可以
使用this.props.searchBarSource
作为Kunukn 提到的。
[注意 - 如果您将getInitialProps
和客户端(浅路由)结合使用,当用户导航到新的客户端路由时,initialProps
将未定义。一种解决方法可能是将initialProps
存储在state
或本地存储中。]
getInitialProps
的重点是在
组件安装。您将始终收到已解决的Promise
on
componentDidMount
,所以你的this.props.searchBarSource
永远不会
为空(或更准确地说,pending
)。
【讨论】:
是的,您将 searchBar 作为道具而不是状态传递是对的,在这样做并将其放入 componentDidMount 函数之后效果很好。那么什么更好呢?将 getInititialProps 用于始终出现在用户面前的道具,并在您想要获取用户首先看不到的数据时使用 componentDidMount?还是只获取 getInitialProps 中的所有内容而不使用 componentDidMount 部分? 前者。例如,我有一个产品页面需要呈现在服务器端以获得最佳用户体验和 SEO。但我只需要提供主要数据即可呈现页面(价格、图像、基本运费)。那将进入getInitialProps
。但是辅助小部件,尤其是在首屏下方的小部件,可以在组件挂载时获取其数据。
在一天结束时,您要做出权衡:您是否希望页面进行更多的服务器端提取并且不加载微调器?在getInitialProps
中获取所有内容。如果您可以为某些事情加载微调器,请获取客户端。以上是关于使用服务器端渲染获取数据的正确方法(Next.js,何时使用 componentDidMount 以及何时使用 componentWillMount)的主要内容,如果未能解决你的问题,请参考以下文章