笔记继续…
一、使用 react-transition-group 扩展,实现css动画
- 官网网址:React Transition Group
- 安装:
npm install react-transition-group --save
1.使用CSSTransition
控制单个元素执行动画:
import { CSSTransition } from 'react-transition-group';
<CSSTransition
in={this.state.xxx} //this.state.xxx数据改变时执行动画
timeout={1000} //动画执行时间
classNames='fade' //类名前缀
unmountOnExit //加上这个属性,会在出场动画执行完毕时,移除这个DOM
//钩子函数 //只写出一个作为举例
onEntered={(e) => { //onEntered在入场动画执行完时执行(e代表被包裹的DOM元素,可以换成其他字符)
e.style.color = 'blue';
}}
appear={true} //当页面第一次渲染时,执行一次入场动画(需要增加appear类)
>
<h1>Hello World</h1>
</CSSTransition>
需要写的css类如下:
.fade-enter, .fade-appear {} //入场动画刚开始
.fade-enter-active, .fade-appear-active {} //入场动画执行过程
.fade-enter-done {} //入场动画执行完毕
.fade-exit {} //出场动画刚开始
.fade-exit-active {} //出场动画执行过程
.fade-exit-done {} //出场动画执行完毕
其中.fade-appear
类和.fade-appear-active
类是上面appear={true}
时才需要添加的。fade
就是上面指定的类名前缀
所有的钩子函数如下:
onEnter //入场动画刚开始时执行
onEntering //入场动画执行时执行
onEntered //入场动画执行完时执行
onExit //出场动画刚开始时执行
onExiting //出场动画执行时执行
onExited //出场动画执行完时执行
2.配合TransitionGroup
来实现操作多个DOM元素执行动画
import { TransitionGroup } from 'react-transition-group';
<TransitionGroup>
{
this.state.list.map((item, index) => {
return (
<CSSTransition
//这里CSSTransition就不需要in属性了,其他属性同上
>
<h1>{item}</h1>
</CSSTransition>
);
});
}
</TransitionGroup>
二、ant design框架初体验
- ant design官网:Ant Design
- 安装:
npm install antd --save
- 使用:
import 'antd/dist/antd.css';
//使用不同的UI组件,需要写上相应的导入语句
//下面input框、button按钮作为举例:
import { Input, Button } from 'antd';
<Input placeholder='antd input' /> //注意UI组件首字母大写
<Button>add</Button>
三、redux
-
安装:
npm install redux --save
-
redux的数据流动关系如下图:
-
打个比方来帮助理解redux的工作机制:store比作仓库,reducer比作一个笔记本,component比作仓库管理员,action比作这个仓库中数据变更的信息。首先,仓库中有一个笔记本,将仓库中杂乱无章的数据有条理的记录下来,每当数据改变时,都会有一个数据更新的信息,仓库管理员根据这个信息更新笔记本,并更新仓库中的数据,仓库中的数据被更新了,页面就会被重新渲染。
具体代码实现:
在src目录
(React的index.js所在的目录)下创建store文件夹
,然后在store文件夹
中创建两个文件:index.js、reducer.js
index.js (store目录下的):
//这个文件的作用是“仓库”
import { createStore } from 'redux';
import reducer from './reducer'; //笔记本
const store = createStore( //创建仓库
reducer, //将笔记本传递给仓库
//在浏览器中使用redux插件
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
export default store;
reducer.js :
//这个文件的作用是笔记本
const defaultState = { //将数据存放在这里
inputValue: '',
list: [
'list1',
'list2',
]
};
//笔记本会默认从仓库那里接受两个参数(state:数据,action:数据变更的信息)
//state = defaultState:将笔记本中记录的数据与仓库中的数据对应起来
export default (state = defaultState, action) => {
return state;
}
index.js(src目录下的):
//用一个input框作为举例
<input onChange={this.handleInputChange} />
handleInputChange(e) {
const action = { //定义这个数据变更的信息
type: 'input_change_value', //给这个信息起一个唯一的名字
value: e.target.value //变更的数据
};
store.dispatch(action); //将这个数据变更的信息传递给store
//dispatch是组件向store发送action的唯一方法
}
当组件向store传递action后,默认的reducer也会接收到这个action,下面这段代码可以证明:
export default (state = defaultState, action) => {
console.log(action);
return state;
}
控制台输出如下:
我在输入框中输入了一个空格
,handleInputChange
方法被执行,action
传递给了store
,默认地reducer
也接收到了这个action
,所以reducer
可以在控制台打印出这个action
既然笔记本接收到了数据变更的信息,那么笔记本记录的数据也要更新:
reducer.js:
//const defaultState = {
// inputValue: '',
// list: [
// 'list1',
// 'list2',
// ]
//};
//export default (state = defaultState, action) => {
if (action.type === 'input_change_value') {
const newState = JSON.parse(JSON.stringify(state)); //对state深拷贝
newState.inputValue = action.value; //更新newState中的inputValue数据
return newState; //将新的数据返回给仓库来更新仓库
}
//由于不能直接修改state,所以要拷贝一份后再做修改
// return state;
//}
index.js(src目录下的):
//constructor(props) {
// super(props);
this.handleStoreChange = this.handleStoreChange.bind(this);
//subscribe用来监听store,一旦store中存储的数据发生变化,就自动执行这个函数
store.subscribe(this.handleStoreChange);
//}
handleStoreChange() {
//store.getState() 用来获取store中最新的数据
this.setState(store.getState()); //用最新的数据来替换仓库中原有的数据
}
数据被更新了,那么页面自然也就被更新了
总结一下:
store提供了三种方法:
store.dispatch();
-----------组件向store传递action的唯一方法store.subscribe();
----------监听store中的数据,一旦数据变化,就执行这个函数store.getState();
------------获取store中的最新的数据
有错误或不足欢迎指正~
待续…