Next.js中如何实现布局侧边栏数据同步更新?
解决Next.js侧边栏数据同步更新问题
方案1:React Context共享状态与刷新逻辑
这是通用的跨组件状态同步方案,适合大多数场景:
- 创建侧边栏数据管理Context
// contexts/SidebarContext.tsx import { createContext, useContext, useState, useEffect, ReactNode } from 'react'; type SidebarContextType = { sidebarData: any[]; refreshSidebar: () => void; }; const SidebarContext = createContext<SidebarContextType | undefined>(undefined); export const SidebarProvider = ({ children }: { children: ReactNode }) => { const [sidebarData, setSidebarData] = useState<any[]>([]); const fetchSidebarData = async () => { const res = await fetch('/api/sidebar-data'); const data = await res.json(); setSidebarData(data); }; useEffect(() => { fetchSidebarData(); }, []); const refreshSidebar = () => { fetchSidebarData(); }; return ( <SidebarContext.Provider value={{ sidebarData, refreshSidebar }}> {children} </SidebarContext.Provider> ); }; export const useSidebar = () => { const context = useContext(SidebarContext); if (!context) { throw new Error('useSidebar必须在SidebarProvider内部使用'); } return context; };
- 在
_app.tsx中注入Provider
// _app.tsx import { SidebarProvider } from '../contexts/SidebarContext'; import Layout from '../components/Layout'; function MyApp({ Component, pageProps }) { return ( <SidebarProvider> <Layout> <Component {...pageProps} /> </Layout> </SidebarProvider> ); } export default MyApp;
- 侧边栏组件使用Context数据
// components/Sidebar.tsx import { useSidebar } from '../contexts/SidebarContext'; const Sidebar = () => { const { sidebarData } = useSidebar(); return ( <div className="sidebar"> {sidebarData.map(item => ( <div key={item.id}>{item.name}</div> ))} </div> ); }; export default Sidebar;
- Index页面调用刷新方法
// pages/index.tsx import { useSidebar } from '../contexts/SidebarContext'; const Index = () => { const { refreshSidebar } = useSidebar(); const handleUpdate = async () => { // 发送UPDATE请求 await fetch('/api/update-sidebar-data', { method: 'PUT', body: JSON.stringify({ /* 你的更新数据 */ }), headers: { 'Content-Type': 'application/json' } }); // 更新完成后触发侧边栏数据刷新 refreshSidebar(); }; return ( <button onClick={handleUpdate}>更新数据</button> ); }; export default Index;
方案2:使用SWR自动缓存刷新(适合已用SWR的项目)
SWR自带缓存和重新验证机制,能简化数据刷新逻辑:
- 侧边栏组件用SWR获取数据
// components/Sidebar.tsx import useSWR from 'swr'; const fetcher = (url: string) => fetch(url).then(res => res.json()); const Sidebar = () => { const { data: sidebarData } = useSWR('/api/sidebar-data', fetcher); return ( <div className="sidebar"> {sidebarData?.map(item => ( <div key={item.id}>{item.name}</div> ))} </div> ); }; export default Sidebar;
- Index页面触发SWR重新验证
// pages/index.tsx import useSWR from 'swr'; const fetcher = (url: string) => fetch(url).then(res => res.json()); const Index = () => { const { mutate } = useSWR('/api/sidebar-data', fetcher); const handleUpdate = async () => { await fetch('/api/update-sidebar-data', { method: 'PUT', body: JSON.stringify({ /* 你的更新数据 */ }), headers: { 'Content-Type': 'application/json' } }); // 触发SWR重新拉取侧边栏数据 mutate(); }; return ( <button onClick={handleUpdate}>更新数据</button> ); }; export default Index;
方案3:props传递刷新函数(适合简单场景)
如果项目不需要复杂状态管理,直接通过_app.tsx传递刷新逻辑:
_app.tsx管理侧边栏数据与刷新方法
// _app.tsx import { useState, useEffect } from 'react'; import Layout from '../components/Layout'; function MyApp({ Component, pageProps }) { const [sidebarData, setSidebarData] = useState<any[]>([]); const fetchSidebarData = async () => { const res = await fetch('/api/sidebar-data'); const data = await res.json(); setSidebarData(data); }; useEffect(() => { fetchSidebarData(); }, []); return ( <Layout sidebarData={sidebarData}> <Component {...pageProps} refreshSidebar={fetchSidebarData} /> </Layout> ); } export default MyApp;
- Index页面接收并调用刷新函数
// pages/index.tsx type IndexProps = { refreshSidebar: () => Promise<void>; }; const Index = ({ refreshSidebar }: IndexProps) => { const handleUpdate = async () => { await fetch('/api/update-sidebar-data', { method: 'PUT', body: JSON.stringify({ /* 你的更新数据 */ }), headers: { 'Content-Type': 'application/json' } }); await refreshSidebar(); }; return ( <button onClick={handleUpdate}>更新数据</button> ); }; export default Index;
- Layout组件传递数据给侧边栏
// components/Layout.tsx type LayoutProps = { children: React.ReactNode; sidebarData: any[]; }; const Layout = ({ children, sidebarData }: LayoutProps) => { return ( <div className="layout"> <Sidebar data={sidebarData} /> <main>{children}</main> </div> ); }; export default Layout;
内容的提问来源于stack exchange,提问作者Sandheep Kumar Patro
相关产品推荐
相关产品推荐

