什么是redux redux入门教程
原创redux定义
- redux是做某事的特殊目的
状态管理的js库 - 它可以用于本机js,react,vue,angular和其他项目,但基本上。react配合使用
- 角色:集中管理react应用程序中有多个组件
共享的状态
在什么情况下redux
- 一个组件的状态需要随时可供其他组件使用(共享)
- 一个组件需要更改另一个组件的状态(通信)
redux流程图

三大原则
- 单一数据源
- 整个应用程序的
state存储在object tree还有这个object tree只存在于独一无二的store中。
- 整个应用程序的
State是只读的- 唯一改变
state方法是触发(dispatch)action
- 唯一改变
- 使用
纯函数执行修改的步骤
Action Creators
角色:创建 action 对象( action 可以不止一个)
const addStuduent = data => ({ type:ADD_STUDENT, data })
Action对象
- 该操作的对象
- 包含两个属性:
type:标识属性,值为字符串,唯一,必需属性。data:数据属性、任意值类型、可选属性
- 例子:
{ type:ADD_STUDENT , data:{name:tom, age:18} }
调用方法: store.dispatch(addStudent(data))
异步Action
由于 Action Creators 创建的对象必须是 action对象 而普通对象不能创建异步任务,因此创建一个 Action 最佳实践是使用 Redux Thunk中间件 。
通过使用指定的 middleware(中间件) , Action Creators 除了返回 action对象 函数也可以返回。在这点上,这 action Creator 就成为了 thunk 。
当 Action Creators 返回函数时,此函数为 Redux Thunk middleware 执行死刑。这个函数不需要保持纯净;API请求。此函数还可以 dispatch action ,就像 dispatch 前面定义的同步 action 一样。
如何使用:
- 从
redux-thunk引入thunk - 从
redux引入applyMiddleware -
createStore()时,添加applyMiddleware(thunk)方法// redux/store.js
//引入createStore,专门用于创建redux最核心的store对象 import {createStore,applyMiddleware} from redux //引入为Count组件服务reducer import countReducer from ./reducers/count //引入redux-thunk,用于支持异步action import thunk from redux-thunk //暴露store export default createStore(countReducer,applyMiddleware(thunk))
在使用该中间件之后, Action Creators 您不仅可以创建 action 对象,您还可以创建异步 action 函数,通常在 action 在函数中调用同步 action
// redux/actions/count.js
import {INCREMENT,DECREMENT} from ./constant
//同步action,就是指action的值为Object类型的一般对象
export const createIncrementAction = data => ({type:INCREMENT,data})
export const createDecrementAction = data => ({type:DECREMENT,data})
//异步action,就是指action的值是一个函数。,异步action同步通常被调用在action,异步action这是没有必要的。
export const createIncrementAsyncAction = (data,time) => {
return (dispatch)=>{
setTimeout(()=>{
dispatch(createIncrementAction(data))
},time)
}
}
ps:中间件方法不是必需的,可以在组件中调用。 store.dispatch() 当在外层增加定时器功能,以达到异步效果。
Reducer
- 功能:用于初始化状态和处理状态
-
加工,按老的
state和action,生成新的state纯函数const initState = 0 //初始化状态 export default function countReducer(preState=initState,action){ //从action获取对象:type、data const {type,data} = action //根据type决定如何处理数据 switch (type) { case increment: return preState + data case decrement: return preState - data default: return preState } }
注意点:
- Redux当第一次执行时,
state为undefined,此时我们可以借用机器来设置并返回初始应用程序。state。 - Reducer函数是一个
纯函数,不允许对原件进行修改state - 在
defaultCase返回原始的state。遇到未知action一定要把原件退回state。
合并Reducers
每个 reducer 只负责管理大局 state 它对此负有部分责任。每个 reducer 的 state 参数是不同的,对应于它管理的零件。 state 数据
Redux 提供了 combineReducers() 要合并所有的 reducer
import { combineReducers } from redux
const todoApp = combineReducers({
visibilityFilter,
todos
})
export default todoApp
上面的文字是等同的
export default function todoApp(state = {}, action) {
return {
visibilityFilter: visibilityFilter(state.visibilityFilter, action),
todos: todos(state.todos, action)
}
}
Store
- 将
state、action、reducer相联对象 - Redux该应用程序只有一个
store - 如何获取此对象
import {createStore} from reduximport reducer from ./reducersconst stroe = createStore(reducer),createStore第二个参数是可选的,用于设置state初始状态
- 3个api
getState():得到statedispatch(action):分发action,触发reducer调用,生成新的statesubscribe(listener):注册监听,当新的state自动呼叫
Redux 该应用程序只有一个 store 。当您需要拆分数据处理逻辑时,应该使用它。 reducer组合 与其创建多个 store 。使用 combineReducers() 将多个 reducer 合二为一。
react-redux模型

容器组件和表示组件(UI组件)
react-redux是一种基于容器组件和表示组件分离的开发思想

- 容器组件:负责任的和redux通信,将结果提供给表示组件
- 演示组件:不能使用任何redux的api,只负责页面呈现、交互等。
创建容器组件
官员们不建议编写容器组件,而是使用它。react-redux提供的 connect() 方法来生成
connect() 方法优势:配对react已经进行了性能优化,以避免许多不必要的重复渲染。
- 在使用
connect()方法需要在此之前定义mapStateToProps和mapDispatchToProps两个函数
mapStateToProps指定当前state映射到演示文稿props在中,返回值是一个对象。mapDispatchToProps接收dispatch()方法,并将所需的注入返回到表示组件。props中的回调方法,返回值是对象或函数。
- 接着使用
connect()创建容器组件
以Count组件示例:
// containers/Count/index.jsx
import React, { Component } from react
import {
createIncrementAction,
createDecrementAction,
createIncrementAsyncAction
} from ../../redux/count_action
import {connect} from react-redux
//定义演示组件
class Count extends Component {
state = {}
increment = ()=>{
const {value} = this.selectNumber
this.props.jia(value*1)
}
decrement = ()=>{
const {value} = this.selectNumber
this.props.jian(value*1)
}
incrementIfOdd = ()=>{
const {value} = this.selectNumber
if(this.props.count % 2 !== 0){
this.props.jia(value*1)
}
}
incrementAsync = ()=>{
const {value} = this.selectNumber
this.props.jiaAsync(value*1,500)
}
render() {
return (
目前的总和是:{this.props.count}
)
}
}
/*
1.mapStateToProps该函数返回一个对象;
2.在返回的对象中key正如所传递的UI组件props的key,value正如所传递的UI组件props的value
3.mapStateToProps通行证
*/
function mapStateToProps(state){
return {count:state}
}
/*
1.mapDispatchToProps该函数返回一个对象;
2.在返回的对象中key正如所传递的UI组件props的key,value正如所传递的UI组件props的value
3.mapDispatchToProps用于传递操作状态的方法。
*/
function mapDispatchToProps(dispatch){
return {
jia:number => dispatch(createIncrementAction(number)),
jian:number => dispatch(createDecrementAction(number)),
jiaAsync:(number,time) => dispatch(createIncrementAsyncAction(number,time)),
}
}
//使用connect()()创建和公开Count的容器组件
export default connect(mapStateToProps,mapDispatchToProps)(Count)
无需事先声明,即可在此处进行代码优化。 mapStateToProps 和 mapDispatchToProps ,直接将这两个方法的返回值带入 connect() 方法
export default connect(
// mapStateToProps的简写
state => ({count:state}),
// mapDispatchToProps的简写
{
jia:createIncrementAction,
jian:createDecrementAction,
jiaAsync:createIncrementAsyncAction,
}
)(Count)
传递Store
所有容器组件均可访问 Store ,因此您可以手动收听。一种方法是接受它 props 传递到所有容器组件的表单的。但这太麻烦了,因为它必须被使用。 Store 将表示组件包装为一层,因为它恰好呈现组件树中的容器组件。
建议的方法是使用指定的react-redux组件 <Provider> 来魔法般的让所有容器组件均可访问 Store ,而不必明确地传递它。您只需要在呈现根组件时使用它。
// src/index.js
import React from react
import { render } from react-dom
import { Provider } from react-redux
import { createStore } from redux
import todoApp from ./reducers
import App from ./components/App
let store = createStore(todoApp)
render(
,
document.getElementById(root)
)
redux和react-redux的区别
- redux是用于国家管理的js库,react-redux是react绑定库
- redux组件直接访问
Store,react-redux组件通过connect()连接容器组件和显示组件 - 获取
State不同的方式,redux使用store.getState(),react-redux使用mapStateToProps函数传递 - 触发
action不同的方式,redux使用store.dispatch(),react-redux使用mapDispatchToProps函数传递
redux的缺点
- 组件所需的数据必须由父组件传递,而不是
flux中直接从store取。 - 当更新与组件相关的数据时,父组件将重新
render,可能很有效,或者需要写得复杂。shouldComponentUpdate做出判断。
版权声明
所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除
itfan123


