一:redux介绍以及使用
redux简介
redux是react中进行state状态管理的JS库(并不是react插件) 一般是管理多个组件中共享数据状态
1 redux组成部分
store:用来存储数据 reducer:真正的来管理数据 actionCreators:创建action,交由reducer处理 view: 用来使用数据,在这里,一般用react组件来充当
2 需要使用redux的项目
用户的使用方式复杂 不同身份的用户有不同的使用方式(比如普通用户和管理员) 多个用户之间可以协作 与服务器大量交互,或者使用了WebSocket View要从多个来源获取数据
3 从组件层面考虑,什么样子的需要redux
某个组件的状态,需要共享 某个状态需要在任何地方都可以拿到 一个组件需要改变全局状态 一个组件需要改变另一个组件的状态
4 redux执行流程
1.创建store 从redux工具中取出createStore去生成一个store 2.创建一个reducer 然后将其传入到createStore中辅助store的创建 reducer是一个纯函数,接收当前状态和action,返回一个状态,返回什么store的状态就是什么,需要注意的是,不能直接操作当前状态,而是需要返回一个新的状态,想要给store创建默认状态其实就是给reducer一个参数创建默认值 3.组件通过调用store.getState方法来使用store中的数据 4.组件产生用户操作 调用actionCreator的方法创建一个action,利用store.dispatch方法传reducer 5.reducer对action上的标示性信息做出判断后对新状态进行处理,然后返回新状态,这个时候store的数据就会发生改变,reducer返回什么状态,store.getState就可以获取什么状态 6.我们可以在组件中,利用store.subscribe(callback)方法去订阅数据的变化 也就是可以传入一个函数,当数据变化的时候,传入的函数会执行,在这个函数中让组件去获取最新的状态
二:redux应用
1 安装redux
npm i redux --save
2 新增Count 组件
绑定事件调用store.dispatch方法(参数为action)传递reducer
import store from '../../redux/store'
export default class Count extends Component {
add = ()=>{
const { value } = this.refs.selectVal;
store.dispatch({type:"add",data:value*1})
}
sub = ()=>{
const { value } = this.refs.selectVal;
store.dispatch({type:"sub",data:value*1})
}
subAsync = ()=>{
const { value } = this.refs.selectVal;
setTimeout(()=>{
store.dispatch({type:'add',data:value*1})
},500)
}
render() {
return (
<div>
<p>计算出的数值为: {store.getState()}</p>
<select ref="selectVal" style={{width:"50px"}}>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button onClick={this.add}>+</button>
<button onClick={this.sub}>-</button>
<button onClick={this.subAsync}>-</button>
</div>
)
}
}
3 src下新建store文件,index.js
1 引入redux中的createStore函数,创建一个store
2 createStore调用时要传入一个为其服务的reducer
3 暴露store对象
import {createStore} from 'redux'
import reducer from './reducers'
export default createStore(reducer)
4 store文件下新建reducers.js
1.reducer的本质是一个函数,接收:preState,action,返回加工后的状态
2.reducer有两个作用:初始化状态,加工状态
3.reducer被第一次调用时,是store自动触发的,
传递的preState是undefined,
传递的action是:{type:'@@REDUX/INIT_a.2.b.4}
const initialization = 0
function reducers(preState=initialization,action){
const {type,data} = action
if(type ==="add"){
return data + preState
}else if(type ==="sub"){
return preState - data
}else{
return 0
}
}
export default reducers
5 在根路径index.js调用store.subscribe方法驱动页面刷新
ReactDOM.render(<App/>,document.getElementById('root'))
store.subscribe(() => {
ReactDOM.render(<App />, document.getElementById("root"));
});
三:异步拆分actions
将异步任务放在store中执行异步actions
1 store下index.js文件添加代码
安装redux-thunk中间件解决异步问题
yarn add redux-thunk
import {createStore,applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
export default createStore(reducer,applyMiddleware(thunk))
2 store文件下新建actions.js
1.store文件下新建constant.js放置容易写错的type值
2.同步action方法拆分
3.异步action接收两个参数,需要返回一个函数,接收参数dispatch
import {INCREMENT,DECREMENT} from './constant'
export const add = data => ({type:INCREMENT,data})
export const sub = data => ({type:DECREMENT,data})
export const addAsync = (data,time) => {
return (dispatch)=>{
setTimeout(()=>{
dispatch(add(data))
},time)
}
}
3 constant.js
一种规范,防止变量重复造成误解(引入错误)
export const INCREMENT = 'add'
export const DECREMENT = 'sub'
4 组件中调用
add = ()=>{
const { value } = this.refs.selectVal;
store.dispatch(add(value*1))
}
addAsync = ()=>{
const { value } = this.refs.selectVal;
store.dispatch(addAsync(value*1,500))
}
四:react-redux的使用
1 react-redux概念及方法
1.UI组件:不能使用任何redux的api,只负责页面的呈现、交互等。
2.容器组件:负责和redux通信,将结果交给UI组件
新建容器组件用于和redux通信 调用connect(mapStateToProps,mapDispatchToProps)(UI组件)方法 接收两个参数都为函数 1 处理传递状态 mapStateToProps:映射状态,返回值是一个对象 2 处理传递状态的方法 mapDispatchToProps:映射操作状态的方法,返回值是一个对象,容器组件中的store是靠props传进去的,而不是在容器组件中直接引mapDispatchToProps,也可以是一个对象
2 react-redux和redux区别
1 redux和组件进行对接的时候是直接在组件中进行创建。 react-redux是运用,一个组件和store对接,使在组件里的所有组件都能共享store里的数据,还要使用connect将组件和react连接。 2 获取state的方式不一样 redux获取state是直接通过store.getState()。 react-redux获取state是通过mapStateToProps函数,只要state数据变化就能获取最新数据 3 触发action的方式不一样。 redux是使用dispatch直接触发,来操作store的数据。 react-redux是使用mapDispathToProps函数然后在调用dispatch进行触发
3 react-redux具体使用
/引入Count的UI组件
import count from '../../pages/count'
import {add,sub,addAsync} from '../../store/actions'
import {connect} from 'react-redux'
function mapStateToProps (state){
return {count:state}
}
function mapDispatchToProps (dispatch){
return {
add:number => dispatch(add(number)),
sub:number => dispatch(sub(number)),
addAsync:(number,time) => dispatch(addAsync(number,time)),
}
}
export default connect(mapStateToProps,mapDispatchToProps)(count)
修改count组件为ui组件拆除redux功能 通过this.props可以拿到视图组件传递过来的数据方法
import React, { Component } from 'react'
export default class Count extends Component {
add = ()=>{
const { value } = this.refs.selectVal;
this.props.add(value*1)
}
sub = ()=>{
const { value } = this.refs.selectVal;
this.props.sub(value*1)
}
addAsync = ()=>{
const { value } = this.refs.selectVal;
this.props.addAsync(value*1,1000)
}
}
在App.js文件,引入store,改为显示ui组件
import Ui from "./components/ui"
import store from "./store/index"
function App() {
return (
<div >
<Ui store={store}/>
</div>
);
}
export default App;
|