面试题答案
一键面试实现思路
- 路由匹配与 API 调用:在 Next.js 的嵌套路由中,利用
useRouter
钩子获取当前路由信息。根据路由信息构建请求参数,调用后端 API 获取对应的菜单数据。 - 状态管理:
- Redux:将获取到的菜单数据存入 Redux store。通过 action 来触发数据的获取和更新。在组件中使用
connect
或者useSelector
和useDispatch
钩子来连接组件与 store,确保数据一致性。 - React Context:创建一个上下文对象,在顶层组件中提供该上下文,将菜单数据作为上下文的值。各级子组件通过
useContext
钩子来获取和更新数据,保持数据一致性。
- Redux:将获取到的菜单数据存入 Redux store。通过 action 来触发数据的获取和更新。在组件中使用
- 数据一致性与交互流畅性:通过状态管理方案,确保各级菜单使用相同数据源。当数据更新时,所有依赖该数据的组件会自动重新渲染,保证交互流畅性。
关键代码示例
使用 Redux
- 安装依赖:
npm install redux react-redux
- 创建 Redux store 和 actions:
// store.js import { createStore } from'redux'; const initialState = { menuData: [] }; const menuReducer = (state = initialState, action) => { switch (action.type) { case 'FETCH_MENU_SUCCESS': return { ...state, menuData: action.payload }; default: return state; } }; const store = createStore(menuReducer); export default store; // actions.js import { FETCH_MENU_SUCCESS } from './actionTypes'; import axios from 'axios'; export const fetchMenuData = () => async (dispatch) => { try { const response = await axios.get('/api/menu'); dispatch({ type: FETCH_MENU_SUCCESS, payload: response.data }); } catch (error) { console.error('Error fetching menu data:', error); } };
- 在 Next.js 页面中使用:
// pages/[...menu].js import React from'react'; import { useRouter } from 'next/router'; import { useSelector, useDispatch } from'react-redux'; import { fetchMenuData } from '../actions'; const MenuPage = () => { const router = useRouter(); const menuData = useSelector((state) => state.menuData); const dispatch = useDispatch(); React.useEffect(() => { dispatch(fetchMenuData()); }, [dispatch]); return ( <div> {/* 渲染菜单数据 */} </div> ); }; export default MenuPage;
使用 React Context
- 创建 Context:
// MenuContext.js import React from'react'; const MenuContext = React.createContext(); export default MenuContext;
- 在顶层组件中提供 Context:
// _app.js import React, { useState, useEffect } from'react'; import MenuContext from '../MenuContext'; import axios from 'axios'; const MyApp = ({ Component, pageProps }) => { const [menuData, setMenuData] = useState([]); useEffect(() => { const fetchMenu = async () => { try { const response = await axios.get('/api/menu'); setMenuData(response.data); } catch (error) { console.error('Error fetching menu data:', error); } }; fetchMenu(); }, []); return ( <MenuContext.Provider value={menuData}> <Component {...pageProps} /> </MenuContext.Provider> ); }; export default MyApp;
- 在子组件中使用 Context:
// pages/[...menu].js import React from'react'; import { useRouter } from 'next/router'; import MenuContext from '../MenuContext'; const MenuPage = () => { const router = useRouter(); const menuData = React.useContext(MenuContext); return ( <div> {/* 渲染菜单数据 */} </div> ); }; export default MenuPage;