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

React非父子组件中,能否通过一个组件的onClick事件触发另一组件功能?

非父子关系的React组件完全可以实现跨组件的状态同步和方法调用,你的场景属于同级组件通信,最简单的实现方案是使用React官方推荐的「状态提升」逻辑,将共享的抽屉显隐状态放到两个组件的共同父组件App中维护,再通过props传递给需要的组件即可,无需引入额外的状态管理工具。

注意事项

你当前自定义的抽屉组件名和Material UI自带的Drawer组件重名,会引发引用冲突,首先将自定义抽屉组件重命名为AppDrawer避免冲突。


分步实现代码

1. 修改独立抽屉组件 AppDrawer.js

import Drawer from '@mui/material/Drawer';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import InboxIcon from '@mui/icons-material/Inbox';
import MailIcon from '@mui/icons-material/Mail';

// 接收父组件传递的显隐状态和关闭方法
export const AppDrawer = ({ open, onClose }) => {
  return (
    <div>
      <Drawer
        variant="temporary"
        anchor="left"
        open={open}
        onClose={onClose}
      >
        <div />
        <List>
          {["Inbox", "Starred", "Send email", "Drafts"].map((text, index) => (
            <ListItem button key={text}>
              <ListItemIcon>
                {index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
              </ListItemIcon>
              <ListItemText primary={text} />
            </ListItem>
          ))}
        </List>
      </Drawer>
    </div>
  );
};

2. 修改 Header.js

移除内部维护的open状态和toggleDrawer逻辑,改为接收父组件传递的切换方法:

import IconButton from '@mui/material/IconButton';
import MenuIcon from '@mui/icons-material/Menu';

// 接收父组件传递的抽屉切换方法
export const Header = ({ toggleDrawer }) => {
  return (
    <header role="banner" className="header header-beta header-mobile">
      <div className="header__content" >
        <div className="header__nav">
          <div style={{margin: 'auto', paddingRight: '4px'}}>
            <IconButton
              color="default"
              aria-label="open drawer"
              edge="start"
              onClick={toggleDrawer}
              className="round-button round-button--minimal round-button--icon js-trigger-drawer-left"
            >
              <span className="round-button__content">
                <i className="icon icon--sm">
                  <MenuIcon />
                </i>
              </span>
            </IconButton>
          </div>
        </div>  
      </div>
    </header>
  );
};

3. 修改 App.js

将共享状态和切换逻辑提升到父组件,同时引入两个子组件并传递对应props:

import { useState } from 'react';
import { Header } from './Header';
import { AppDrawer } from './AppDrawer';

export default function App() {
  // 提升到父组件维护的抽屉显隐状态
  const [open, setOpen] = useState(false);

  const toggleDrawer = event => {
    if (
      event.type === "keydown" &&
      (event.key === "Tab" || event.key === "Shift")
    ) {
      return;
    }
    setOpen(!open);
  };

  return (
    <>
      <Header toggleDrawer={toggleDrawer} />
      <AppDrawer open={open} onClose={toggleDrawer} />
    </>
  );
}

拓展说明

如果后续项目复杂度提升,存在大量跨层级组件需要共享状态,你也可以选择React Context、Redux、Zustand等状态管理方案实现组件通信,但当前场景下状态提升是最简单且无额外依赖成本的实现方式。

内容的提问来源于stack exchange,提问作者Hania Salman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:06:03