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

如何在使用makeStyles后动态修改Material UI样式实现搜索框点击展开效果

搜索框点击展开效果实现方案

以下是两种可直接落地的实现方式:

方案1:利用makeStyles动态传参特性实现

  • 在样式定义中直接接收状态参数,根据参数值返回对应样式
  • 组件内部维护展开状态,点击按钮时切换状态即可触发样式更新
import { useState } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import IconButton from '@material-ui/core/IconButton';
import SearchIcon from '@material-ui/icons/Search';

const useStyles = makeStyles((theme) => ({
  searchInput: {
    // 接收传入的isExpanded参数动态返回样式
    width: (props) => props.isExpanded ? 200 : 0,
    padding: (props) => props.isExpanded ? '0 8px' : 0,
    border: (props) => props.isExpanded ? '1px solid #ccc' : "none",
    // 加过渡属性实现平滑展开/收起效果
    transition: 'all 0.3s ease',
  },
}));

function ExpandableSearchBar() {
  const [isExpanded, setIsExpanded] = useState(false);
  // 将状态作为参数传入useStyles
  const classes = useStyles({ isExpanded });

  function onClick() {
    setIsExpanded(!isExpanded);
  }

  return (
    <div className="component-wrapper">
      <IconButton onClick={onClick} aria-label="Search">
        <SearchIcon />
      </IconButton>
      <input className={classes.searchInput} type="text" />
    </div>
  );
}

方案2:多类名切换实现

  • 分别定义收缩、展开两种状态的独立样式类
  • 点击时根据当前状态拼接输入框的类名即可,逻辑更直观易维护
import { useState } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import IconButton from '@material-ui/core/IconButton';
import SearchIcon from '@material-ui/icons/Search';

const useStyles = makeStyles((theme) => ({
  // 公共基础样式
  searchInput: {
    transition: 'all 0.3s ease',
  },
  // 收缩状态样式
  inputCollapsed: {
    width: 0,
    padding: 0,
    border: "none",
  },
  // 展开状态样式
  inputExpanded: {
    width: 200,
    padding: '0 8px',
    border: '1px solid #ccc'
  }
}));

function ExpandableSearchBar() {
  const [isExpanded, setIsExpanded] = useState(false);
  const classes = useStyles();

  function onClick() {
    setIsExpanded(!isExpanded);
  }

  // 根据状态拼接类名
  const inputClass = `${classes.searchInput} ${isExpanded ? classes.inputExpanded : classes.inputCollapsed}`

  return (
    <div className="component-wrapper">
      <IconButton onClick={onClick} aria-label="Search">
        <SearchIcon />
      </IconButton>
      <input className={inputClass} type="text" />
    </div>
  );
}

两种方案都可以实现需求,可根据代码习惯选择。

内容的提问来源于stack exchange,提问作者Enzo Dtz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 15:54:03