You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 02:05:23