React—10—过渡动画;React使用CSS的几种方式;React如何给元素动态添加类;
一、react-transition-grou过渡动画
react-transition-group本质是自动给我们添加类和删除类,具体的过渡动画效果还是要我们自己写。
(一)CSSTransition组件
- 第一类,开始状态:对于的类是-appear、-enter、exit;
- 第二类:执行动画:对应的类是-appear-active、-enter-active、-exit-active;
- 第三类:执行结束:对应的类是-appear-done、-enter-done、-exit-done;
appear appear是初次显示动画,和enter的区别是只有第一次显示会走apper,后面的显示都走enter。 enter enter是元素显示的动画,即进入动画,进入有三个状态,初始的enter、执行动画期间的enter-active、执行结束后的enter-done/ 并且react是给元素先加入enter类,在加入enter-active类, 最终经过我们写的timeout时间后,把enter和enter-active都去掉,加入enter-done类。 所以,如果我们想实现一个隐入隐出的效果, 可以在enter类里写opacity:0 然后react会立马在enter类保留的基础上,在添加一个enter-acitve类,这个时候enter-acitve类就写 opacity:1; transition:all 2s ease; 这样,这个元素的opacity属性就从0变到了1,然后由于我们加了一个transition的效果,所以opacity在变化的时候,会有动态效果。 最终在经过timeout时间后,react会把enter和enter-active类都去掉,然后加入enter-done类。 exit exit是元素消失的动画 用法和enter一样。
import React, { PureComponent } from 'react';
import { CSSTransition } from 'react-transition-group';
import './style.css';
// 编写一个组件
class App extends PureComponent {
constructor() {
super();
this.state = {
isShow: true
};
}
render() {
const { isShow } = this.state;
return (
<div>
<button onClick={e => this.setState({ isShow: !isShow })}>切换</button>
<CSSTransition in={isShow} appear classNames="foo" timeout={2000} unmountOnExit={true}>
<div>
<h1>过渡动画</h1>
</div>
</CSSTransition>
</div>
);
}
}
export default App;
样式:::::::::::::::::::::::::
1.3CSSTransition常见对应的属性:
in:触发进入或者退出状态
-
如果添加了unmountOnExit={true},那么该组件会在执行退出动画结束后被移除掉;
-
当in为true时,触发进入状态,会添加-enter、-enter-acitve的class开始执行动画,当动画执行结束后,会移除两个class,
-
并且添加-enter-done的class;
-
当in为false时,触发退出状态,会添加-exit、-exit-active的class开始执行动画,当动画执行结束后,会移除两个class,并
-
且添加-enter-done的class;
classNames:动画class的名称, 决定了在编写css时,对应的class名称:比如card-enter、card-enter-active、card-enter-done;
timeout:过渡动画的时间
appear:是否在初次进入添加动画(需要和in同时为true)
unmountOnExit:退出后是否卸载组件
1.4 CSSTransition对应的钩子函数:
(二)SwitchTransition
CSSTransition:一个是单独组件的显示和消失。
SwitchTransition:一个两个组件的切换。
key,以便 TransitionGroup 正确地识别到每个组件,方便key不同时,TransitionGroup 来切换。import React, { useState } from 'react';
import { TransitionGroup, CSSTransition } from 'react-transition-group';
import './styles.css'; // 包含过渡效果的 CSS 样式
// 定义五个简单的组件
const ComponentOne = () => <div className="component">组件一</div>;
const ComponentTwo = () => <div className="component">组件二</div>;
const ComponentThree = () => <div className="component">组件三</div>;
const ComponentFour = () => <div className="component">组件四</div>;
const ComponentFive = () => <div className="component">组件五</div>;
function App() {
const [activeIndex, setActiveIndex] = useState(0);
// 组件列表
const components = [
<ComponentOne key="one" />,
<ComponentTwo key="two" />,
<ComponentThree key="three" />,
<ComponentFour key="four" />,
<ComponentFive key="five" />
];
// 切换到下一个组件
const handleNext = () => {
setActiveIndex((prevIndex) => (prevIndex + 1) % components.length);
};
return (
<div>
<button onClick={handleNext}>切换组件</button>
<TransitionGroup>
<CSSTransition
key={activeIndex} // 使用 activeIndex 作为 key
timeout={500}
classNames="fade"
>
{components[activeIndex]}
</CSSTransition>
</TransitionGroup>
</div>
);
}
export default App;
.fade-enter { opacity: 0; } .fade-enter-active { opacity: 1; transition: opacity 500ms; } .fade-exit { opacity: 1; } .fade-exit-active { opacity: 0; transition: opacity 500ms; } .component { padding: 20px; border: 1px solid #ccc; margin-top: 10px; }
(三)TransitionGroup
CSSTransition:单独组件切换(显示和消失)
SwitchTransition:两个组件的切换。
TransitionGroup:一组组件中,增加或删除某个组件。

二、React如何使用CSS
2.1内联样式
2.2普通CSS
2.3CSS modules
2.4 CSS in JS
2.5 css in js的重点框架, styled-components
- 这个组件会被自动添加上一个不重复的class;
- styled-components会给该class添加相关的样式;
- 支持直接子代选择器或后代选择器,并且直接编写样式;
- 可以通过&符号获取当前元素;
- 直接伪类选择器、伪元素等;

2.6 styled-components的props属性和attrs属性
import React, { PureComponent } from 'react';
import { AppWrapper, PartWrapper, DefaultWrapper } from './style';
// 编写一个组件
class App extends PureComponent {
constructor() {
super();
this.state = {
isShow: true,
fontSize: '32px',
color: 'skyBlue'
};
}
render() {
const { isShow, fontSize, color } = this.state;
return (
<div>
<button onClick={e => this.setState({ isShow: !isShow })}>切换</button>
<AppWrapper>
<h1 className="head">头部</h1>
<div className="body">body</div>
<footer>
脚{/* 给样式组件传递一些变量 */}
<PartWrapper fontSize={fontSize} color={color}>
<div className="section">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
</PartWrapper>
<DefaultWrapper color2={color}>
<div className="section2">section2</div>
<div className="section3">section3</div>
</DefaultWrapper>
</footer>
</AppWrapper>
</div>
);
}
}
export default App;
import styled from 'styled-components'; export const AppWrapper = styled.div` .head { color: red; } .body { background-color: #f2f2f2; &:hover { background-color: skyblue; } } footer { color: blue; } `; export const PartWrapper = styled.div` .section { width: 100px; height: 50px; margin: 0 auto; color: ${props => props.color}; font-size: ${props => props.fontSize}; border: 1px solid skyblue; display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: space-around; align-items: center; } `; // attrs属性,可以给组件添加属性,这样除了父组件穿的propos属性,还有自己定义的属性。 // color2属性: 可以先判断父组件里是否有传值,有则取父组件传的值,没有则默认给值。 // color3属性: 直接给默认值 export const DefaultWrapper = styled.div.attrs(props => ({ color2: props.color2 || 'red', color3: '#fff' }))` .section2 { color: ${props => props.color2}; } .section3 { color: ${props => props.color3}; } `;

项目中,全局变量和组件的样式都用style-components来写,style-components也支持less的全局变量定义、变量使用、嵌套语法等,还可以通过props获取动态变量。
现代css也支持变量和嵌套语法了,less给我的感觉是用处不大了,可能只有一个预处理器把css的一些写法转化成老浏览器能识别的作用吧。
注意: 我本来想试着在style-component使用less定义的变量@primary-color,发现无法获取。但是css原生定义的变量
:root{
--primary-color:red
}
style-components是可以获取到的。
原因CSS 变量是浏览器原生支持的特性,styled-components 可以直接访问这些变量,因为它们是在浏览器运行时解析的。
Less 是一种 CSS 预处理器,它的变量在编译时被替换为具体的值,编译后生成的 CSS 文件中不再保留变量信息。styled-components 无法直接访问 Less 变量,因为它们在运行时已经不存在。
所以 style-components想使用变量,要么使用css原生变量配置,要么直接配置一个全局js文件然后在所有需要用到的文件导入即可,如果嫌所有要用到的文件都要导入麻烦那么就使用theme配置即可。
三、React动态给元素添加class


第一步: npm install classNames
第二步:
import React, { PureComponent } from 'react';
import classNames from 'classnames';
// 编写一个组件
class App extends PureComponent {
constructor() {
super();
this.state = {
isFoo: true
};
}
render() {
const { isFoo } = this.state;
return (
<div>
<h1 className={classNames({ foo: isFoo })}>头部</h1>
</div>
);
}
}
export default App;

浙公网安备 33010602011771号