有关Redux的使用方法
详细请查看中文文档
1 redux是什么
redux是一个专门用于做状态管理的JS库,它可以用在react, angular, vue等项目中, 但基本与react配合使用,用于集中式管理react应用中多个组件共享的状态。
2 什么情况下可以使用redux
1.某个组件的状态,需要让其他组件可以随时拿到(组件间共享数据)。
2.一个组件需要改变另一个组件的状态(组件间通信)。
3 redux流程
4 redux的三个核心概念
1.Action:Action 是把数据从应用传到 store 的有效载荷。它是 store 数据的唯一来源。一般来说你会通过 store.dispatch() 将 action 传到 store。Action 本质上是 JavaScript 普通对象。除了 type 字段外,action 对象的结构完全由你自己决定。
一般可以包含2个属性
type:标识属性, 值为字符串, 唯一, 必要属性
data:数据属性, 值类型任意, 可选属性
{ type: 'add_person',data:{name: 'lx',age:18} }
2.Reducer:Reducers 指定了应用状态的变化如何响应 actions 并发送到 store 的,记住 actions 只是描述了有事情发生了这一事实,并没有描述应用如何更新 state。
(用于初始化状态、加工状态)根据旧的state和action, 产生新的state的纯函数。
永远不要在 reducer 里做这些操作:
修改传入参数;
执行有副作用的操作,如 API 请求和路由跳转;
调用非纯函数,如 Date.now() 或 Math.random()。
3.Store:将state、action、reducer联系在一起的对象。Redux 应用只有一个单一的 store。
(1)如何生成store对象?
import {createStore} from 'redux'
import reducer from './reducers'
const store = createStore(reducer)
(2)此对象的方法?
getState(): 获取state
dispatch(action): 分发action, 触发reducer调用, 产生新的state
subscribe(listener): 注册监听, 当产生了新的state时, 自动调用
5 redux的核心API
1.createstore():创建包含指定reducer的store对象
2.store对象:redux库最核心的管理对象
(1)核心方法:
getState()
dispatch(action)
subscribe(listener)
(2)具体用法:
store.getState()
store.dispatch({type:'INCREMENT', number})
store.subscribe(render)
applyMiddleware():应用上基于redux的中间件(插件库)
combineReducers():合并多个reducer函数
6 实现小案例
计数器小案例:使用下拉框选择每次需要加或减的数字,点击按钮进行修改count,功能包括加,减,当前count为奇数进行加,异步加数字。
在src/components/Count文件夹下新建Count.jsx
import React, { Component } from 'react';
import store from '../../redux/store';
//引入actioncreator,专门用于创建action对象
import {createAddAction,createSubAction,createAddAsyncAction} from '../../redux/count_action'
class Count extends Component {
add = () => {
const {value} = this.selectNum
// store.dispatch({type:'add',data: parseInt(value)})
store.dispatch(createAddAction(parseInt(value)))
}
sub = () => {
const {value} = this.selectNum
// store.dispatch({type:'sub',data: parseInt(value)})
store.dispatch(createSubAction(parseInt(value)))
}
addOdd = () => {
const {value} = this.selectNum
const count = store.getState()
if(count % 2 !== 0){
store.dispatch({type:'add',data: parseInt(value)})
}
}
addAsync = () => {
const {value} = this.selectNum
// setTimeout(function(){
// store.dispatch({type:'add',data: parseInt(value)})
// },1000)
store.dispatch(createAddAsyncAction(parseInt(value),1000))
}
componentDidMount(){
//检测redux变化,只要变化,就调用render
store.subscribe(()=>{
this.setState({})
})
}
render() {
return (
<div>
<h1>当前值为:{store.getState()}</h1>
<select ref={(current)=>{this.selectNum = current}}>
<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.addOdd}>奇数+</button>
<button onClick={this.addAsync}>异步+</button>
</div>
);
}
}
export default Count;
App.js代码
import React, { Component } from 'react'
import Count from './components/Count/Count.jsx'
export default class App extends Component {
render() {
return (
<div>
<Count></Count>
</div>
)
}
}
在src/redux下新建store.js
//createStore用于创建redux中的store对象
import {createStore,applyMiddleware} from 'redux'
//引入为Count组件服务的reducer
import countReducer from './count_reducer'
//引入redux-thunk,用于支持异步action
import thunk from 'redux-thunk'
export default createStore(countReducer,applyMiddleware(thunk))
在src/redux新建count_action.js
//该文件专门为Count组件生成对象
// import store from "./store"
export function createAddAction(data){
return {type: 'add',data }
}
export function createSubAction(data){
return {type: 'sub',data }
}
//异步action,指action返回值为函数,同步action指action返回值为object类型的一般对象,异步action异步都会调用同步action
export function createAddAsyncAction(data,time){
return function(dispatch){
setTimeout(()=>{
// store.dispatch(createAddAction(data))
dispatch(createAddAction(data))
},time)
}
}
在src/redux下新建count_reducer.js
//函数会接受两个参数,之前的状态,动作对象
export default function countReducer(preState,action){
if(preState === undefined){
preState = 0
}
//从action对象中取出type,data
const {type,data} = action
//加工数据
switch (type) {
case 'add':
return preState + data;
case 'sub':
return preState - data
default:
return preState
}
}
7 注意
1.redux只负责管理状态,想要状态的改变驱动着页面的改变,需要自己手动编写。
(1)可以在组件中的componentDidMount生命周期进行编写
componentDidMount(){
//检测redux变化,只要变化,就调用render
store.subscribe(()=>{
this.setState({})
})
}
当this.setState()被调用的时候,不仅会更新state,React会重新调用render方法来重新渲染UI。
(2)在index.js中监测store中状态的改变,一旦发生改变重新渲染App组件
store.subscribe(()=>{
ReactDOM.render(
<App />,
document.getElementById('root')
)
})
2.使用异步action时需要注意的地方
(1)首先yarn add redux-thunk,并配置在store中
(2)创建action的函数不再返回一般对象,而是一个函数,该函数中写异步任务。
(3)异步任务有结果后,分发一个同步的action去真正操作数据。
(4)异步action不是必须要写的,完全可以等待异步任务的结果了再去分发同步action。
- 本文作者: étoile
- 版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!