13.2 SwitchTransition
SwitchTransition中主要有一个属性:mode,有两个值
- on-out:表示新组件先进入,旧组件再移除;
- out-in:表示就组件先移除,新组建再进入;
如何使用SwitchTransition呢?
- SwitchTransition组件里面要有CSSTransition或者Transition组件,不能直接包裹你想要切换的组件;
- SwitchTransition里面的CSSTransition或Transition组件不再像以前那样接受in属性来判断元素是何种状态,取而代之的是key属性;
import React, { PureComponent } from 'react'
import { SwitchTransition, CSSTransition } from 'react-transition-group'
export default class SwitchTransitionDemo extends PureComponent {
constructor() {
super();
this.state = {
isOn: true
}
}
render() {
const { isOn } = this.state;
return (
<div>
<SwitchTransition mode="out-in">
<CSSTransition
key={isOn ? "on" : "off"}
classNames="fade"
timeout={300}
>
<button onClick={() => this.setState({ isOn: !isOn })}>
{isOn ? "ON" : "OFF"}
</button>
</CSSTransition>
</SwitchTransition>
</div>
)
}
}
.fade-enter {
opacity: 0;
}
.fade-enter-active {
opacity: 1;
transition: opacity 300ms;
}
.fade-exit {
opacity: 1;
}
.fade-exit-active {
opacity: 0;
transition: opacity 300ms;
}
13.3 TransitionGroup
当我们有一组动画时,需要将这些CSSTransition放入到一个TransitionGroup中来完成动画:
import React, { PureComponent } from 'react'
import { TransitionGroup, CSSTransition } from 'react-transition-group'
export default class TransitionGroupDemo extends PureComponent {
constructor() {
super();
this.state = {
items: [1, 2, 3]
}
}
addItem = () => {
this.setState((state) => ({
items: [...state.items, state.items.length + 1]
}));
}
removeItem = (id) => {
this.setState((state) => ({
items: state.items.filter(item => item !== id)
}));
}
render() {
return (
<div>
<button onClick={this.addItem}>添加</button>
<TransitionGroup>
{this.state.items.map(item => (
<CSSTransition
key={item}
classNames="fade"
timeout={300}
>
<div style={{ margin: 8, display: 'inline-block' }}>
{item}
<button onClick={() => this.removeItem(item)} style={{ marginLeft: 8 }}>删除</button>
</div>
</CSSTransition>
))}
</TransitionGroup>
</div>
)
}
}
.fade-enter {
opacity: 0;
transform: scale(0.9);
}
.fade-enter-active {
opacity: 1;
transform: scale(1);
transition: all 300ms;
}
.fade-exit {
opacity: 1;
transform: scale(1);
}
.fade-exit-active {
opacity: 0;
transform: scale(0.9);
transition: all 300ms;
}
14、Redux
14.1 什么是redux
Redux 是一个用于 JavaScript 应用程序的状态管理库,主要用于解决复杂应用中的状态管理问题。它的核心思想是提供一种可预测的状态管理机制,通过集中式存储(Store)来管理应用的所有状态,从而简化状态更新和组件间的数据共享。
Redux 的设计围绕四个核心概念展开:Store、State、Action 和 Reducer。
- Store(存储)
- Store 是 Redux 中的全局唯一对象,用于保存应用的所有状态。
- 它提供了几个重要方法:
getState()
:获取当前状态。dispatch(action)
:发送 Action 以触发状态更新。subscribe(listener)
:注册监听器,当状态变化时触发回调13。
- State(状态)
- State 是应用的状态树,表示应用的当前状态。
- 它是不可变的,只能通过 Action 来修改。
- Action(动作)
- Action 是一个普通 JavaScript 对象,用于描述发生了什么。
- 每个 Action 至少包含一个
type
属性(标识动作类型),还可以携带额外的数据(如payload
)。 - 例如:
{ type: 'ADD_TODO', payload: { text: 'Learn Redux' } }
37。
- Reducer(规约器)
- Reducer 是一个纯函数,接收当前 State 和 Action 作为参数,并返回新的 State。
- 它负责描述 Action 如何改变 State,且必须是无副作用的37。
14.2 redux的工作流程
Redux 的状态更新遵循以下流程:
- 触发 Action:用户操作(如点击按钮)会触发一个 Action。
- 分发 Action:通过
dispatch(action)
将 Action 发送到 Store。 - Reducer 处理:Store 调用 Reducer,传入当前 State 和 Action,Reducer 根据逻辑返回新的 State。
- 更新 State:新的 State 被保存到 Store 中,所有订阅的组件会收到通知并更新视图
代码:
// 使用redux
const redux = require('redux')
// 数据
const initialState = {
counter: 0
}
// reducer
function reducer(state = initialState, action) {
switch (action.type) {
case "INCREMENT":
return { ...state, counter: state.counter + 1 };
case "DECREMENT":
return { ...state, counter: state.counter - 1 };
case "ADD_NUMBER":
return { ...state, counter: state.counter + action.num };
default:
return state;
}
}
// 创建store
const store = redux.createStore(reducer)
// actions
const action1 = { type: "INCREMENT" }
const action2 = { type: "DECREMENT" }
const action3 = { type: "ADD_NUMBER", num: 5 }
// 派发action
store.dispatch(action1)
store.dispatch(action2)
store.dispatch(action3)
// 查看结果
console.log(store.getState())
将代码进行拆分:
创建store/index.js文件:创造store
import { legacy_createStore } from 'redux'; import reducer from './reducer.js'; const store = legacy_createStore(reducer); export default store;
创建store/reducer.js文件:执行action
import { ADD_NUMBER } from "./constans.js"; const defaultState = { counter : 0 } function reducer(state = defaultState , action){ switch(action.type){ case ADD_NUMBER : return {...state,counter:state.counter + action.num} default : return state; } } export default reducer;
创建store/actionCreators.js文件:action定义
import {ADD_NUMBER} from './constans.js' export const addAction = (num) => { return { type: ADD_NUMBER, num:5 } }
创建store/constants.js文件:常量
export const ADD_NUMBER = "ADD_NUMBER"
14.3 react当中的redux
在react当中拿到数据、订阅数据、分派函数
import React, { PureComponent } from 'react'
import { addAction } from '../store/actionCreators'
import store from '../store'
export default class Home extends PureComponent {
// 构造函数,初始化组件状态
constructor() {
super();
// 设置初始状态,从store中获取counter的值
this.state = {
num: store.getState().counter
}
}
// 组件挂载后,订阅store的变化
componentDidMount() {
// 订阅store的变化,当store中的状态发生变化时,更新组件状态
this.unsubscribe = store.subscribe(() => {
this.setState({
num: store.getState().counter
})
})
}
// 组件卸载前,取消订阅
componentWillUnmount() {
// 取消订阅,避免内存泄漏
this.unsubscribe && this.unsubscribe();
}
// 渲染组件
render() {
return (
<div>
<h2>Home</h2>
{/* 显示当前num的值 */}
<h3>Num: {this.state.num}</h3>
{/* 点击按钮,dispatch一个action,增加num的值 */}
<button onClick={() => store.dispatch(addAction(6))}>+6</button>
</div>
)
}
}