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

如何在ReactCSSTransitionGroup过渡中使用Material-UI主题?

实现方案:Material-UI主题复用 + ReactCSSTransitionGroup动画

没问题,我来帮你一步步搞定这个需求——既要用muiThemeable注入主题样式,又要通过ReactCSSTransitionGroup实现元素的进出动画,还得复用Material-UI主题里的配色,完全可行!

第一步:确认依赖安装

首先确保你已经装了必要的包:

npm install material-ui react-addons-css-transition-group --save
# 或者用yarn
yarn add material-ui react-addons-css-transition-group

第二步:用muiThemeable注入主题

把需要访问主题的组件用muiThemeable高阶组件包裹,这样组件就能拿到theme属性,直接复用主题里的预设颜色(比如theme.palette.primary[500]、theme.palette.text.primary这些)。

第三步:结合ReactCSSTransitionGroup实现动画

这里有两种常用的方式来复用主题颜色,你可以根据自己的习惯选择:

方式一:内联样式 + 动态过渡

直接把主题颜色写进元素的内联样式里,同时给ReactCSSTransitionGroup配置过渡属性:

import React from 'react';
import { muiThemeable } from 'material-ui/styles';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';

class AnimatedList extends React.Component {
  state = {
    items: ['Item 1', 'Item 2', 'Item 3']
  };

  addItem = () => {
    const newItem = `Item ${this.state.items.length + 1}`;
    this.setState(prevState => ({
      items: [...prevState.items, newItem]
    }));
  };

  removeItem = (index) => {
    this.setState(prevState => ({
      items: prevState.items.filter((_, i) => i !== index)
    }));
  };

  render() {
    const { theme } = this.props;
    const listItems = this.state.items.map((item, index) => (
      <div
        key={item}
        style={{
          padding: '10px',
          margin: '5px 0',
          backgroundColor: theme.palette.primary[100],
          color: theme.palette.text.primary,
          transition: 'all 0.3s ease'
        }}
      >
        {item}
        <button
          onClick={() => this.removeItem(index)}
          style={{ marginLeft: '10px', backgroundColor: theme.palette.accent[500], color: 'white', border: 'none', padding: '5px 10px' }}
        >
          删除
        </button>
      </div>
    ));

    return (
      <div>
        <button onClick={this.addItem} style={{ marginBottom: '10px', backgroundColor: theme.palette.primary[500], color: 'white', border: 'none', padding: '8px 15px' }}>
          添加项目
        </button>
        <ReactCSSTransitionGroup
          transitionName={{
            enter: 'fade-enter',
            enterActive: 'fade-enter-active',
            leave: 'fade-leave',
            leaveActive: 'fade-leave-active'
          }}
          transitionEnterTimeout={300}
          transitionLeaveTimeout={300}
        >
          {listItems}
        </ReactCSSTransitionGroup>
      </div>
    );
  }
}

// 用muiThemeable包裹组件,注入theme
export default muiThemeable()(AnimatedList);

然后在全局CSS里写动画的关键帧:

.fade-enter {
  opacity: 0;
  transform: translateY(-20px);
}

.fade-enter-active {
  opacity: 1;
  transform: translateY(0);
}

.fade-leave {
  opacity: 1;
  transform: translateY(0);
}

.fade-leave-active {
  opacity: 0;
  transform: translateY(20px);
}

方式二:动态生成CSS类(结合主题)

如果你更喜欢用CSS类而不是内联样式,可以通过theme属性配合Material-UI的withStyles生成带主题颜色的样式:

import React from 'react';
import { muiThemeable, withStyles } from 'material-ui/styles';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';

// 用withStyles结合主题生成样式
const styles = theme => ({
  listItem: {
    padding: '10px',
    margin: '5px 0',
    backgroundColor: theme.palette.primary[100],
    color: theme.palette.text.primary,
    transition: 'all 0.3s ease'
  },
  addButton: {
    marginBottom: '10px',
    backgroundColor: theme.palette.primary[500],
    color: 'white',
    border: 'none',
    padding: '8px 15px',
    cursor: 'pointer'
  },
  deleteButton: {
    marginLeft: '10px',
    backgroundColor: theme.palette.accent[500],
    color: 'white',
    border: 'none',
    padding: '5px 10px',
    cursor: 'pointer'
  }
});

class AnimatedList extends React.Component {
  // 状态和方法和方式一一致,此处省略...

  render() {
    const { classes } = this.props;
    const listItems = this.state.items.map((item, index) => (
      <div key={item} className={classes.listItem}>
        {item}
        <button onClick={() => this.removeItem(index)} className={classes.deleteButton}>
          删除
        </button>
      </div>
    ));

    return (
      <div>
        <button onClick={this.addItem} className={classes.addButton}>
          添加项目
        </button>
        <ReactCSSTransitionGroup
          transitionName="fade"
          transitionEnterTimeout={300}
          transitionLeaveTimeout={300}
        >
          {listItems}
        </ReactCSSTransitionGroup>
      </div>
    );
  }
}

// 先包裹withStyles处理样式,再用muiThemeable注入主题
export default muiThemeable()(withStyles(styles)(AnimatedList));

对应的全局CSS和方式一完全相同,负责定义动画的过渡效果。

关键注意点

  • muiThemeable会把当前的Material-UI主题作为theme属性传递给组件,你可以直接访问theme.palette下的所有颜色变量。
  • ReactCSSTransitionGroup的transitionName可以是字符串(对应全局CSS类),也可以是对象(自定义各阶段的类名)。
  • 动画的过渡时长要和transitionEnterTimeout、transitionLeaveTimeout保持一致,避免出现动画异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:43:56