MST

星途 面试题库

面试题:React状态管理与SSR下的条件渲染优化

在一个React应用中使用Next.js进行服务器端渲染(SSR),并且使用MobX进行状态管理。应用中有一个复杂的用户权限系统,不同权限的用户在页面上看到的内容和布局都不同(例如,管理员看到完整的菜单和操作按钮,普通用户只能看到部分菜单)。请阐述如何优化状态管理和条件渲染,以确保在SSR环境下高效地渲染页面,同时避免在客户端和服务器端渲染不一致的问题。并给出关键代码示例。
12.8万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

优化状态管理

  1. 服务器端状态初始化: 在服务器端渲染时,需要根据请求的用户信息初始化MobX状态。例如,通过解析JWT(JSON Web Token)获取用户权限信息。
// server.js
import { createServer } from 'http';
import { renderToString } from 'next/server';
import { Provider } from'mobx-react';
import { getServerSideProps } from './pages/index';
import { configure } from'mobx';
import { UserStore } from '../stores/UserStore';

configure({ enforceActions: 'always' });

const server = createServer(async (req, res) => {
    const userStore = new UserStore();
    // 假设这里从请求头解析JWT获取用户权限信息
    const token = req.headers.authorization;
    if (token) {
        // 解析JWT获取用户权限
        const decoded = parseJWT(token);
        userStore.setPermissions(decoded.permissions);
    }
    const context = {};
    const pageProps = await getServerSideProps({ req });
    const html = renderToString(
        <Provider UserStore={userStore}>
            <App {...pageProps} />
        </Provider>
    );
    res.writeHead(200, {
        'Content-Type': 'text/html'
    });
    res.end(`
        <!DOCTYPE html>
        <html>
            <head>
                <title>My Next.js App</title>
            </head>
            <body>
                <div id="__next">${html}</div>
                <script src="/_next/static/chunks/main.js"></script>
            </body>
        </html>
    `);
});

server.listen(3000, () => {
    console.log('Server is running on port 3000');
});
  1. 共享状态: 确保在客户端和服务器端使用相同的状态管理逻辑。在客户端,重新初始化MobX状态并与服务器端传递的状态同步。
// pages/_app.js
import React from'react';
import { Provider } from'mobx-react';
import { UserStore } from '../stores/UserStore';
import App from 'next/app';

function MyApp({ Component, pageProps }) {
    const userStore = new UserStore();
    // 假设从pageProps获取服务器端传递的用户权限信息
    if (pageProps.userPermissions) {
        userStore.setPermissions(pageProps.userPermissions);
    }
    return (
        <Provider UserStore={userStore}>
            <Component {...pageProps} />
        </Provider>
    );
}

export default MyApp;

优化条件渲染

  1. 基于状态的条件渲染: 在组件中根据MobX状态进行条件渲染。例如,在菜单组件中根据用户权限渲染不同的菜单项。
// components/Menu.js
import React from'react';
import { observer } from'mobx-react';
import { useStore } from '../stores/useStore';

const Menu = observer(() => {
    const { userStore } = useStore();
    return (
        <ul>
            <li>Home</li>
            {userStore.hasPermission('admin') && <li>Admin Panel</li>}
            <li>Profile</li>
        </ul>
    );
});

export default Menu;
  1. 避免不一致问题: 确保在服务器端和客户端渲染时,条件渲染逻辑是相同的。这意味着条件判断逻辑应该基于共享的MobX状态,而不是依赖于客户端特定的逻辑(如浏览器特性检测等)。

关键代码总结

  1. UserStore
// stores/UserStore.js
import { makeObservable, observable, action } from'mobx';

class UserStore {
    permissions = [];

    constructor() {
        makeObservable(this, {
            permissions: observable,
            setPermissions: action
        });
    }

    setPermissions(permissions) {
        this.permissions = permissions;
    }

    hasPermission(permission) {
        return this.permissions.includes(permission);
    }
}

export { UserStore };
  1. useStore Hook
// stores/useStore.js
import { useContext } from'react';
import { UserStoreContext } from './UserStoreContext';

export const useStore = () => {
    const stores = useContext(UserStoreContext);
    return stores;
};
  1. UserStoreContext
// stores/UserStoreContext.js
import { createContext } from'react';

const UserStoreContext = createContext();

export { UserStoreContext };

通过以上步骤,可以在Next.js的SSR环境下,结合MobX有效地优化状态管理和条件渲染,避免客户端和服务器端渲染不一致的问题。