面试题答案
一键面试1. 使用React进行服务器端渲染时数据获取的关键步骤
- 路由匹配与数据预取
- 在服务器端,通过路由匹配确定当前请求对应的组件。例如,使用
react - router - dom
的StaticRouter
,它可以根据请求的URL来匹配路由。 - 对于每个需要数据的路由组件,在渲染前进行数据预取。可以在组件的
getInitialProps
(Next.js 风格)或自定义的静态方法中发起数据请求。例如,使用axios
库向API发送请求获取数据。
import React from'react'; import axios from 'axios'; const MyPage = ({ data }) => { return ( <div> {data.map(item => ( <p key={item.id}>{item.title}</p> ))} </div> ); }; MyPage.getInitialProps = async () => { const response = await axios.get('/api/data'); return { data: response.data }; }; export default MyPage;
- 在服务器端,通过路由匹配确定当前请求对应的组件。例如,使用
- 数据传递与渲染
- 将预取的数据传递给组件进行渲染。在服务器端渲染时,将数据作为属性传递给组件树的根组件。
- 在客户端,需要再次获取数据或者将服务器端传递下来的数据“激活”。例如,Next.js会自动将服务器端渲染的数据传递到客户端,客户端可以直接使用这些数据。
2. 集成Redux的关键步骤与要点
- 服务器端配置Redux
- 创建Redux的
store
实例,并在服务器端渲染前将预取的数据填充到store
中。 - 使用
Provider
组件将store
传递给React应用。
import React from'react'; import { renderToString } from'react - dom/server'; import { Provider } from'react - redux'; import { createStore } from'redux'; import rootReducer from './reducers'; import MyApp from './MyApp'; const serverSideRender = async (req, res) => { const store = createStore(rootReducer); // 数据预取并填充到store const response = await axios.get('/api/data'); store.dispatch({ type: 'FETCH_DATA_SUCCESS', payload: response.data }); const html = renderToString( <Provider store={store}> <MyApp /> </Provider> ); res.send(` <!DOCTYPE html> <html> <head> <title>SSR with Redux</title> </head> <body> <div id="root">${html}</div> <script> window.__PRELOADED_STATE__ = ${JSON.stringify(store.getState())} </script> <script src="/client - bundle.js"></script> </body> </html> `); }; export default serverSideRender;
- 创建Redux的
- 客户端同步状态
- 在客户端,从
window.__PRELOADED_STATE__
中获取服务器端传递下来的状态,并使用该状态创建store
。
import React from'react'; import { hydrate } from'react - dom'; import { Provider } from'react - redux'; import { createStore } from'redux'; import rootReducer from './reducers'; import MyApp from './MyApp'; const preloadedState = window.__PRELOADED_STATE__; const store = createStore(rootReducer, preloadedState); hydrate( <Provider store={store}> <MyApp /> </Provider>, document.getElementById('root') );
- 在客户端,从
- 注意要点
- 数据预取时机:确保在渲染组件树之前完成数据预取并填充到
store
,这样才能在渲染时提供正确的数据。 - 状态一致性:服务器端和客户端的
store
初始化和数据处理逻辑要保持一致,避免出现状态不一致的问题。
- 数据预取时机:确保在渲染组件树之前完成数据预取并填充到
3. 集成Mobx的关键步骤与要点
- 服务器端配置Mobx
- 创建Mobx的
stores
实例,并在服务器端渲染前将预取的数据填充到stores
中。 - 使用
Provider
(来自mobx - react
)将stores
传递给React应用。
import React from'react'; import { renderToString } from'react - dom/server'; import { Provider } from'mobx - react'; import MyStore from './MyStore'; import MyApp from './MyApp'; const serverSideRender = async (req, res) => { const myStore = new MyStore(); // 数据预取并填充到store const response = await axios.get('/api/data'); myStore.setData(response.data); const html = renderToString( <Provider myStore={myStore}> <MyApp /> </Provider> ); res.send(` <!DOCTYPE html> <html> <head> <title>SSR with Mobx</title> </head> <body> <div id="root">${html}</div> <script> window.__PRELOADED_STATE__ = ${JSON.stringify(myStore.getData())} </script> <script src="/client - bundle.js"></script> </body> </html> `); }; export default serverSideRender;
- 创建Mobx的
- 客户端同步状态
- 在客户端,从
window.__PRELOADED_STATE__
中获取服务器端传递下来的状态,并使用该状态初始化stores
。
import React from'react'; import { hydrate } from'react - dom'; import { Provider } from'mobx - react'; import MyStore from './MyStore'; import MyApp from './MyApp'; const preloadedState = window.__PRELOADED_STATE__; const myStore = new MyStore(); myStore.setData(preloadedState); hydrate( <Provider myStore={myStore}> <MyApp /> </Provider>, document.getElementById('root') );
- 在客户端,从
- 注意要点
- 数据预取时机:和Redux类似,要在渲染前完成数据预取并更新
stores
。 - 响应式更新:Mobx依赖响应式编程,确保在服务器端和客户端正确处理数据变化的响应,避免出现数据不同步的视觉问题。
- 数据预取时机:和Redux类似,要在渲染前完成数据预取并更新