MST
星途 面试题库

面试题:React服务器端渲染的数据获取与状态管理

在使用React进行服务器端渲染时,如何有效地进行数据获取并集成常见的状态管理库(如Redux或Mobx)?描述实现过程中的关键步骤和需要注意的要点,比如数据预取时机与状态同步等。
19.0万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

1. 使用React进行服务器端渲染时数据获取的关键步骤

  1. 路由匹配与数据预取
    • 在服务器端,通过路由匹配确定当前请求对应的组件。例如,使用react - router - domStaticRouter,它可以根据请求的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;
    
  2. 数据传递与渲染
    • 将预取的数据传递给组件进行渲染。在服务器端渲染时,将数据作为属性传递给组件树的根组件。
    • 在客户端,需要再次获取数据或者将服务器端传递下来的数据“激活”。例如,Next.js会自动将服务器端渲染的数据传递到客户端,客户端可以直接使用这些数据。

2. 集成Redux的关键步骤与要点

  1. 服务器端配置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;
    
  2. 客户端同步状态
    • 在客户端,从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')
    );
    
  3. 注意要点
    • 数据预取时机:确保在渲染组件树之前完成数据预取并填充到store,这样才能在渲染时提供正确的数据。
    • 状态一致性:服务器端和客户端的store初始化和数据处理逻辑要保持一致,避免出现状态不一致的问题。

3. 集成Mobx的关键步骤与要点

  1. 服务器端配置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;
    
  2. 客户端同步状态
    • 在客户端,从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')
    );
    
  3. 注意要点
    • 数据预取时机:和Redux类似,要在渲染前完成数据预取并更新stores
    • 响应式更新:Mobx依赖响应式编程,确保在服务器端和客户端正确处理数据变化的响应,避免出现数据不同步的视觉问题。