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

React JS中传递CSS类名:跨组件点击修改组件宽度

解决React跨组件修改样式(宽度)及CSS类名传递问题

问题描述

点击SideBar组件中的BiCaretLeft按钮,修改App组件里<aside>标签的宽度,同时需要了解React中传递CSS类名的方法。现有SideBar和App组件代码如下:

原SideBar组件代码

import { useState } from "react";
import { BiCaretLeft } from "react-icons/bi";

const SideBar = () => {
  const [open, setOpen] = useState(true);

  return (
    <div className="relative">
      <BiCaretLeft 
        className={`${
          open ? "w-72" : "w-20"
        } bg-red-400 absolute cursor-pointer -right-3 top-5 border rounded-full`}
        color="#fff"
        size={25}
        onClick={setOpen(!true)}
      />
    </div>
  );
};

export default SideBar;

原App组件代码

import "./App.css";
import SideBar from "./components/SideBar/SideBar";

function App() {
  return (
    <div className="app flex">
      <aside className="h-screen bg-slate-700"> {/* 需要修改这里的宽度 */}
        <SideBar />
      </aside>
      <main className="flex-1 h-screen"></main>
    </div>
  );
}
export default App;

解决方案

核心思路是状态提升:把控制侧边栏宽度的状态放到父组件App中,通过props将状态和状态更新函数传递给子组件SideBar,子组件触发状态变化后,父组件根据状态切换CSS类名。

步骤1:重构App组件,提升状态

在App中定义控制侧边栏展开/收起的状态,根据状态给<aside>设置不同宽度的类名,同时把状态更新函数传递给SideBar:

import "./App.css";
import SideBar from "./components/SideBar/SideBar";
import { useState } from "react";

function App() {
  // 控制侧边栏是否展开的状态,默认展开
  const [isSidebarOpen, setIsSidebarOpen] = useState(true);

  return (
    <div className="app flex">
      {/* 根据状态切换宽度类名:展开时w-72,收起时w-20 */}
      <aside className={`h-screen bg-slate-700 ${isSidebarOpen ? "w-72" : "w-20"}`}>
        {/* 传递状态更新函数和当前状态给SideBar */}
        <SideBar 
          onToggleSidebar={() => setIsSidebarOpen(!isSidebarOpen)} 
          isOpen={isSidebarOpen} 
        />
      </aside>
      <main className="flex-1 h-screen"></main>
    </div>
  );
}
export default App;

步骤2:修改SideBar组件,接收props并触发状态更新

SideBar不再维护自身状态,而是接收App传递的isOpen状态和onToggleSidebar函数,点击按钮时调用该函数,同时可根据状态切换图标优化交互:

import { BiCaretLeft, BiCaretRight } from "react-icons/bi";

const SideBar = ({ onToggleSidebar, isOpen }) => {
  return (
    <div className="relative">
      {/* 根据侧边栏状态切换图标,提升交互直观性 */}
      {isOpen ? (
        <BiCaretLeft
          className="bg-red-400 absolute cursor-pointer -right-3 top-5 border rounded-full"
          color="#fff"
          size={25}
          onClick={onToggleSidebar}
        />
      ) : (
        <BiCaretRight
          className="bg-red-400 absolute cursor-pointer -right-3 top-5 border rounded-full"
          color="#fff"
          size={25}
          onClick={onToggleSidebar}
        />
      )}
    </div>
  );
};

export default SideBar;

React中传递CSS类名的常见方法

  • 直接通过props传递类名字符串:父组件定义好类名,通过props传给子组件直接使用:
    // 父组件
    <SideBar customClass="w-72 bg-red-400" />
    // 子组件
    const SideBar = ({ customClass }) => <div className={customClass}></div>
    
  • 根据状态动态拼接类名:如解决方案中的示例,父组件根据状态拼接不同类名,适合动态切换样式的场景。
  • 使用类名处理库(如classnames):多条件判断时简化代码:
    import classNames from 'classnames';
    // 父组件中
    const asideClasses = classNames(
      'h-screen',
      'bg-slate-700',
      { 'w-72': isSidebarOpen, 'w-20': !isSidebarOpen }
    );
    <aside className={asideClasses}></aside>
    

原代码问题修正

  1. onClick事件错误:原SideBar中onClick={setOpen(!true)}会在组件渲染时直接执行,应改为箭头函数包裹:onClick={() => setOpen(!open)}(重构后改用父组件传递的函数)。
  2. 状态作用域问题:原SideBar的open状态仅能控制自身元素宽度,无法影响父组件的<aside>,因此必须将状态提升到共同父组件App中。

内容的提问来源于stack exchange,提问作者Timothy Nyambane

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 03:45:35