如何在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
相关产品推荐
相关产品推荐

