如何在Next.js(TypeScript)的另一个组件中复用toggleViewMode?
实现跨组件共享toggleViewMode状态的几种方法
方法一:状态提升(适合组件有共同父组件的场景)
如果两个组件存在共同的父组件,最直接的方式是把状态移到父组件中,再通过props将状态和更新函数传递给子组件。
示例代码:
父组件:
const ParentComponent: NextPage = () => { const [toggleViewMode, setToggleViewMode] = useState(false); return ( <div> {/* 把更新函数传给Pagecontent组件 */} <Pagecontent setToggleViewMode={setToggleViewMode} /> {/* 把状态传给需要使用的另一个组件 */} <AnotherComponent toggleViewMode={toggleViewMode} /> </div> ); };
修改后的Pagecontent组件:
// 定义props类型 interface PagecontentProps { setToggleViewMode: React.Dispatch<React.SetStateAction<boolean>>; } const Pagecontent: NextPage<PagecontentProps> = ({ setToggleViewMode }) => { return ( <input type="checkbox" id="default-toggle" className="sr-only peer" // 使用prev参数确保基于最新状态更新 onClick={() => setToggleViewMode(prev => !prev)} /> ); };
使用状态的目标组件:
interface AnotherComponentProps { toggleViewMode: boolean; } const AnotherComponent: NextPage<AnotherComponentProps> = ({ toggleViewMode }) => { return ( <div className={`mt-2 max-w-lg mx-auto grid gap-5 grid-cols-${toggleViewMode ? '2' : '1'}`}> {/* 组件内容 */} </div> ); };
方法二:使用Context API(适合组件层级深或无直接关联的场景)
如果组件层级复杂,或者没有共同父组件,用Context API实现全局状态共享更高效,避免多层级props传递的麻烦。
示例代码:
创建ViewModeContext.tsx:
import { createContext, useContext, useState, ReactNode } from 'react'; // 定义Context的类型 interface ViewModeContextType { toggleViewMode: boolean; setToggleViewMode: React.Dispatch<React.SetStateAction<boolean>>; } // 创建Context,默认值设为undefined const ViewModeContext = createContext<ViewModeContextType | undefined>(undefined); // 定义Provider组件,包裹需要共享状态的组件树 export const ViewModeProvider = ({ children }: { children: ReactNode }) => { const [toggleViewMode, setToggleViewMode] = useState(false); return ( <ViewModeContext.Provider value={{ toggleViewMode, setToggleViewMode }}> {children} </ViewModeContext.Provider> ); }; // 自定义Hook,简化Context的获取 export const useViewMode = () => { const context = useContext(ViewModeContext); if (!context) { throw new Error('useViewMode必须在ViewModeProvider内部使用'); } return context; };
在_app.tsx中添加Provider:
import { ViewModeProvider } from '../components/ViewModeContext'; function MyApp({ Component, pageProps }) { return ( <ViewModeProvider> <Component {...pageProps} /> </ViewModeProvider> ); } export default MyApp;
修改Pagecontent组件:
const Pagecontent: NextPage = () => { // 从Context中获取更新函数 const { setToggleViewMode } = useViewMode(); return ( <input type="checkbox" id="default-toggle" className="sr-only peer" onClick={() => setToggleViewMode(prev => !prev)} /> ); };
使用状态的目标组件:
const AnotherComponent: NextPage = () => { // 从Context中获取状态值 const { toggleViewMode } = useViewMode(); return ( <div className={`mt-2 max-w-lg mx-auto grid gap-5 grid-cols-${toggleViewMode ? '2' : '1'}`}> {/* 组件内容 */} </div> ); };
注意事项
- 状态提升是React共享状态的基础方案,适合简单组件结构
- Context API适合全局状态共享,能有效避免多层级props传递的问题
- 更新状态时推荐使用
prev => !prev的写法,确保基于最新的状态值进行修改
内容的提问来源于stack exchange,提问作者anmol asghar
相关产品推荐
相关产品推荐

