面试题答案
一键面试生命周期函数执行顺序差异
- 客户端渲染:
constructor
->getDerivedStateFromProps
->render
->componentDidMount
- 服务器端渲染:
constructor
->getDerivedStateFromProps
->render
- 没有
componentDidMount
等仅客户端执行的生命周期函数。在服务器端渲染过程中,组件主要执行到render
阶段,用于生成初始的HTML字符串。
可能导致的业务逻辑问题及解决办法
- 问题示例:
- 假设在
componentDidMount
中发起一个API请求获取数据并更新组件状态。在服务器端渲染时,因为没有componentDidMount
执行,组件初始渲染的HTML中不会包含该数据。当客户端渲染接管后,componentDidMount
执行,数据才被获取并更新状态,这可能导致页面闪烁(初始渲染无数据,后来有数据)。
- 假设在
- 解决办法:
- 方法一:使用
getInitialProps
(Next.js 等框架提供的方式):在Next.js中,可以在页面组件中定义getInitialProps
静态方法。这个方法会在服务器端和客户端渲染时都执行(服务器端优先),可用于获取数据并作为props传递给组件,确保初始渲染就有数据。
import React from'react'; const MyPage = ({ data }) => { return ( <div>{data}</div> ); }; MyPage.getInitialProps = async () => { const response = await fetch('https://example.com/api/data'); const data = await response.json(); return { data }; }; export default MyPage;
- 方法二:在
render
前获取数据:在组件外部获取数据,然后作为props传递给组件。这样在服务器端和客户端渲染时,都能保证数据在render
之前就已准备好。
import React from'react'; const fetchData = async () => { const response = await fetch('https://example.com/api/data'); return await response.json(); }; const MyComponent = ({ data }) => { return ( <div>{data}</div> ); }; const renderMyComponent = async () => { const data = await fetchData(); return <MyComponent data={data} />; }; export default renderMyComponent;
- 方法一:使用