React+TypeScript子组件向父组件传值实现导航切换问题
React + TypeScript 导航组件传值问题及解决方案
已编辑:底部添加解决方案
我有一个基于React和TypeScript创建的项目,父组件(Home)会根据状态变量currentDemo的值展示对应的子组件。需求是实现一个导航组件,点击导航项时展示对应组件:每个导航项关联一个id,点击对应id的导航项就展示同名组件。以下是代码片段:
Home.tsx(父组件)
import React, { useState } from 'react'; import { Intro } from 'app/components/intro/Intro'; import { SidebarNav } from 'app/components/sidebarNav/SidebarNav'; import { ComponentA } from 'app/components/ComponentA/ComponentA'; import { ComponentB } from 'app/components/ComponentB/ComponentB'; export function Home() { // 用状态跟踪当前展示的组件(默认显示Intro) const [currentDemo, setCurrentDemo] = useState('intro'); return ( <> <Header /> <div className="home"> <SidebarNav setCurrentDemo={setCurrentDemo} /> {currentDemo === 'intro' && <Intro />} {currentDemo === 'ComponentA' && <ComponentA/>} {currentDemo === 'ComponentB' && <ComponentB/>} </div> </> ); }
SidebarNav.tsx(子组件)
import React from 'react'; const navData = [ { title: 'Introduction', id: 'intro' }, { title: 'Component A', id: 'ComponentA' }, { title: 'Component B', id: 'ComponentB' } ]; export function SidebarNav(setCurrentDemo: any) { // 目标:将选中导航项的id传递给父组件,更新currentDemo的值 const handleCurrentClick = (id: any) => { if (id === 'intro') { setCurrentDemo('ComponentA'); } else if (id === 'ComponentA') { setCurrentDemo('ComponentB'); } else if (id === 'ComponentB') { setCurrentDemo('intro'); } }; return ( <div className="sidebarNav"> <div className="sidebarNav__container"> {navData?.map((item, index) => ( <div key={index}> <button onClick={() => { handleCurrentClick(item.id); }} id={item.id} > {item.title} </button> </div> ))} </div> </div> ); }
ComponentA和ComponentB的具体实现不影响当前场景。我已经测试过手动设置currentDemo的值可以正常切换组件,也通过console.log(item.id)确认了每个导航项的id是正确的。
现在的问题是:如何将SidebarNav中点击的导航项id传递给Home组件,把currentDemo的值设置为该id?目前点击任何导航元素都会报错:setCurrentDemo不是一个函数,我知道这和状态setter的传递方式有关,但不知道怎么正确处理。
解决方案(仅修改导航组件)
添加Props接口并调整参数接收方式,同时修正点击逻辑以匹配需求:
import React, { SetStateAction } from 'react'; const navData = [ { title: 'Introduction', id: 'intro' }, { title: 'Component A', id: 'ComponentA' }, { title: 'Component B', id: 'ComponentB' } ]; // 定义组件Props的类型接口 interface SidebarNavProps { setCurrentDemo: React.Dispatch<SetStateAction<string>>; } export function SidebarNav(props: SidebarNavProps) { // 解构获取父组件传递的setter函数 const { setCurrentDemo } = props; // 修正点击逻辑:直接将选中的id传给setter const handleCurrentClick = (id: string) => { setCurrentDemo(id); }; return ( <div className="sidebarNav"> <div className="sidebarNav__container"> {navData?.map((item, index) => ( <div key={index}> <button onClick={() => { handleCurrentClick(item.id); }} id={item.id} > {item.title} </button> </div> ))} </div> </div> ); }
内容的提问来源于stack exchange,提问作者dcmswim
相关产品推荐
相关产品推荐

