🚩🚩🚩
💎个人主页: 阿选不出来
💨💨💨
💎个人简介: 一名大二在校生,学习方向前端,不定时更新自己学习道路上的一些笔记.
💨💨💨
💎目前开发的专栏: JS 🍭Vue🍭React🍭
💨💨💨
React——redux
Redux理解
Redux 是 JavaScript 状态容器,提供可预测化的状态管理。
redux是什么
- redux是一个专门用于做状态管理的JS库(不是react插件库)。
- 它可以用在react,angular,vue等项目中,但基本与react配合使用。
- 作用:集中式管理react应用中多个组件共享的状态。
redux的使用场景
- 某个组件的状态,需要让其他组件可以随时拿到(共享)。
- 一个组件需要改变另一个组件的状态(通信)。
- 总体原则:能不用就不用,如果不用比较吃力才考虑使用。
redux的三大原则
- state以单一对象存储在store对象中
- state只读(每次都返回一个新的对象)
- 使用纯函数reducer执行state更新
redux基本使用
下载redux包
npm i redux
代码结构
store.js文件专门用于创建并配置store并暴露
//引入createstore,用于创建store对象import{legacy_createStore as createStore}from'redux'// 引入reducerimport reducer from'./reducers'const store =createStore(reducer)exportdefault store
actions文件夹存放多个为指定组件生成的action对象。
reducers文件夹存放多个为指定组件服务的reducer纯函数。
constant.js文件用于定义action对象中type类型的常量值,便于管理,防止单词的拼写错误。
例:
exportconstINCREMENT='increment'
Redux的三个核心概念
Redux的工作流
- View在redux中会派发action方法
- action通过store的dispatch方法会派发给store
- store接收action,连同之前的state,一起传递给reducer
- reducer返回新的数据给store
- store去改变自己的state
1.action
Action 是把数据从应用(译者注:这里之所以不叫 view 是因为这些数据有可能是服务器响应,用户输入或其它非 view 的数据 )传到 store 的有效载荷。它是 store 数据的唯一来源。一般来说你会通过
store.dispatch()
将 action 传到 store。
constADD_TODO='ADD_TODO'{
type:ADD_TODO,
data:'Bilid my first Redux app'}
action本质为JavaScript普通对象。
action内必须包含
type
属性,值为字符串,表示将要执行的动作,作为唯一标识。
除
type
属性外,action对象的结构完全由你自己决定,通常会传入
data
属性,值为某个组件向reducer函数操作state时传的参数。
在模块化开发中,一个组件可能会需要多个action对象,通常按照下方的写法。
constINCREMENT='INCREMENT'exportconstincrement= data =>({type:INCREMENT,data})...
异步action
例如:点击一个按钮,三秒后让一个
count
数值加一。
当点击按钮后,组件内通过
store.dispatch
将action对象派发给store。
我们在action中返回一个定时器,3秒后调用同步action触发
dispatch
执行加动作。
exportconstincrementAsync=(data,time)=>{return(dispatch)=>{setTimeOut(()=>{dispatch(increment(data))})}}
由于redux本身不支持异步操作。react给我们提供了一个插件 redux-thunk 可以让redux拥有异步操作的能力。
用法:
store.js文件下
import{legacy_createStore as createStore,applyMiddleware}from'redux'import thunk from 'redux-thunk
...exportdefaultcreateStore(reducer,applyMiddleware(thunk))
2.reducer
reducer用于将store发过来的action完成并将结果返回给store,他有两个作用:初始化store和更新store。
reducer接收两个参数preState(旧状态)和action(动作)并返回一个newState(新状态)。
(previousState, action)=> newState
初始化状态
const initState =0//初始化状态
reducer纯函数
functioncount(preState=initState,action){// 从actions对象中获取:type,dataconst{type,data}= action
//根据type决定如何加工数据switch(type){caseINCREMENT:return xxx
...default:return preState
}}
注意:redux的reducer是一个纯函数。纯函数是一类特别的函数。
纯函数的规则:
- 不能改写参数数据。
- 不会产生任何副作用,例如网络请求,输入和输出设备。
- 不能调用Date.now()或Math.random()等不纯的方法。
例如:当我们要对store里的一个数组添加一个对象时:
错误的写法:
preState.unshift(data)
此时,preState这个实参被改写了,reducer不在是纯函数。
正确的写法:
使用对象展开运算符
[data,...preState]
创建了一个新数组。
combineReducers
Redux应用中只有一个单一的store。当多个组件都需要用到store时,便于数据逻辑处理,我们需要使用reducer组合。
redux提供了
combineReducers()
工具类,组合多个reducer。
import{combineReducers}from'redux'//引入多个reducerimport reducer1 from'./reducer1'import reducer2 from'./reducer2'...exportdefaultcombineReducers({
reducer1,
reducer2
})
3.store
前文我们知道了使用
action
描述“发生了什么”,使用
reducers
来根据action更新state的用法。
而 store 就是action 和 reducer 之间的桥梁。
store的创建
//引入createstore,用于创建store对象import{legacy_createStore as createStore}from'redux'// 引入reducerimport reducer from'./reducers'const store =createStore(reducer)
createStore第一个参数传入reducer,第二个参数为可选的,用于设置state初始状态。
Store的职责
- 维持应用的state;
- 提供
getState()
方法获取state; - dispatch(action) 更新state;
- subscribe(listener)注册监听器;
- subscribe(listener)返回的函数注销监听器;
这里需要再强调一下:Redux 和 React 之间没有关系。Redux 支持 React、Angular、Ember、jQuery 甚至纯 JavaScript。
为了让用户监听应用数据改变,Store 允许使用store.subscribe方法设置监听函数,一旦 State 发生变化,就自动执行这个函数。
在src/index.js入口文件中:
import store from'./redux/store'...
store.subscribe(()=>{
root.render(<App/>)})
react-redux
本库并不是 Redux 内置,需要单独安装,是Redux官方提供的React绑定库。
安装
npm i react-redux
redux将组件分为了UI组件和容器组件两类:
- UI组件:不能使用任何redux的api,只负责页面的呈现、交互等。
- 容器组件:负责和redux通信,将结果(采用父子通信)传给UI组件。
Provider
<Provider store>
使组件层级中的
connect()
方法都能够获得 Redux store。
在src/index.jsx文件下:
...
root.render(
<Provider store={store}
<App/>
</Provider>)
目的:让
<App>
所有的后代容器组件都能接收到store。
Connect
用于连接React组件与Redux store。
connect(mapStateToProps,mapDispatchToProps)
- mapStateToProps(state, [ownProps]): stateProps] (Function)- 映射状态。- 该回调函数必须返回一个纯对象,这个对象会与组件的 props 合并。- 如果定义该参数,组件会监听redux store的变化,只要store发生改变,mapStateToProps就会被调用。
- mapDispatchToProps(dispatch, [ownProps])- 映射操作状态的方法。- mapDispatchToProps可以是一个Function,也可以是Object,作用是绑定action创建函数到props上。- 如果传递的是一个对象,那么每个定义在该对象的函数都将被当作Redux action creator,而且这个对象会与 Reduxstore绑定在一起,其中所定义的方法名将作为属性名,合并到组件的 props 中;- 如果传递的是一个函数,该函数将接收一个 dispatch 函数,然后由你来决定如何返回一个对象,这个对象通过 dispatch 函数与action creator 以某种方式绑定在一起。
例:
头部的引入:
import React,{ Component }from'react'import{connect}from'react-redux'import{
increment,
decrement,}from'../../redux/actions/count'
mapDispatchToProps返回值为函数时:
connect(
state=>(count:state.count),
dispatch=>({
increment:number=>dispatch(increment(number)),
decrement:number=>dispatch(decrement(number))}))
mapDispatchToProps返回值为对象时:
采用了对象的简写形式
connect(
state=>(count:state.count),{increment,decrement})
react-redux的开发者工具
redux-devtools-extensionredux这个插件是官方提供的可以查看状态的ui插件,让我们在很多组件的情况下,也能知道每个组件的数据情况,非常贴心。
安装
npm i redux-devtools-extension
配置
import{composeWithDevTools}from'redux-devtools-extension'...const store =createStore(reducer,composeWithDevTools(applyMiddleware(thunk)))
版权归原作者 阿选不出来 所有, 如有侵权,请联系我们删除。