React之6 状态管理器Redux

6.1 Redux成员及其数据流

  • actions
    actions是描述操作的对象,调⽤dispatch时需要传⼊此对象
  • store
    store是整个应⽤的数据存储仓库,把我们全局管理的状态数据存储起来
  • reducers
    reducers接收action并更新store

注意:redux是⼀个单独的数据流框架,是JavaScript的状态容器, 跟react并没有直接的联系,通过redux, 我们可以轻松的对状态进行管理。我们也可以在JQuery在其他的复杂项⽬⾥使⽤redux进⾏数据管理,当我们不知道是否应该是⽤redux的时候,我们都是不需要的,因为只有我们很肯定redux能帮助我们管理好复杂项⽬数据流的时候他才能发挥它的威⼒,简单的项⽬我们只需要state+props+context就够了

Redux数据流的⾛向:
在这里插入图片描述
6.2 编写⼀个累加器程序

  • 安装redux
    npm install redux --save
  • 使⽤redux的步骤
  1. 从redux引⼊createStore⽤来创建数据仓库store
 createStore(reducers[,initialState]) 

createStore是⼀个函数,需要传⼊reducer作为参数,返回值是我们需要的store
initialState初始状态,是可选参数

  1. 在使⽤⻚⾯引⼊数据仓库store
    通过getState()⽅法可以获取到数据仓库⾥的状态数据state
    通过dispatch(action)可以触发更改reducer函数
    每次触发dispatch都会触发store.subscribe()⽅法,⽤来重新触发⻚⾯渲染

store.js

import { createStore } from 'redux'
const firstReducer = (state = 0, action) => {
  switch (action.type) {
    case 'add':
      return state + 1
    case 'reduce':
      return state - 1
    default:
      return state
  }
}
//创建数据仓库,把我们编写的reducer作为参数传入createStore
const store = createStore(firstReducer)
export default store

App.js

import './App.css'
import { Button } from 'antd'
import store from './store'
import React, { Component } from 'react'

export default class App extends Component {

  render() {
    return (
     <div>
       <h1>redux累加器</h1>
       {store.getState()}
       <div>
         <Button onClick={()=>store.dispatch({type:'add'})}>加一</Button>
         <Button onClick={()=>store.dispatch({type:'reduce'})}>减一</Button>
       </div>
     </div>
    )
  }
}

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App';
import * as serviceWorker from './serviceWorker'
import store from './store'

const render=()=>{
  ReactDOM.render(<App />, document.getElementById('root'))
}
render()
serviceWorker.unregister()
//监听数据变化来自动渲染
store.subscribe(render)

6.3 React封装的react-redux进⾏改造累加器
上面每次都要重新调用render,太繁琐。

  • 安装react-redux:
    npm install react=redux --save
  • React-redux提供了两个api
    Provider 顶级组件,功能为给我们提供数据
    connect ⾼阶组件,功能为提供数据和⽅法

store.js不用改

App.js

import './App.css'
import { Button } from 'antd'
import React, { Component } from 'react'
import { connect } from 'react-redux'

//写一个返回数据的方法,供connect使用,connect会把数据转换成props
const mapStateToProps = state => {
  return {
    count: state
  }
}

//写一个dispatch方法,用connect使用,connect会把dispatch转换成props
const mapDispatchToProps = dispatch => {
  return {
    add: () => dispatch({ type: 'add' }),
    reduce: () => dispatch({ type: 'reduce' })
  }
}
class App extends Component {
  render() {
    return (
      <div>
        <h1>redux累加器</h1>
        {this.props.count}
        <div>
          <Button onClick={() => this.props.add()}>加一</Button>
          <Button onClick={() => this.props.reduce()}>减一</Button>
        </div>
      </div>
    )
  }
}
export default connect(mapStateToProps, mapDispatchToProps)(App)

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import store from './store'
import { Provider } from 'react-redux'

ReactDOM.render(
  <Provider store={store}>
    {' '}
    <App />
  </Provider>,
  document.getElementById('root')
)

6.4 使用⾼阶组件装饰器模式进⾏简化封装代码
修改App.js

import './App.css'
import { Button } from 'antd'
import React, { Component } from 'react'
import { connect } from 'react-redux'

//装饰器
@connect(
  state => ({ count: state }),
  dispatch => ({
    add: () => dispatch({ type: 'add' }),
    reduce: () => dispatch({ type: 'reduce' })
  })
)
class App extends Component {
  render() {
    return (
      <div>
        <h1>redux累加器</h1>
        {this.props.count}
        <div>
          <Button onClick={() => this.props.add()}>加一</Button>
          <Button onClick={() => this.props.reduce()}>减一</Button>
        </div>
      </div>
    )
  }
}
export default App

6.5 redux中间件
由于redux reducer默认只⽀持同步,实现异步任务或者延时任务时,我们就要借助中间件middleware的⽀持了

redux数据流:
在这里插入图片描述
两个中间件:

  • redux-thunk ⽀持我们reducer在异步操作结束后⾃动执⾏
    安装 redux-thunk
    npm install redux-thunk --save
  • redux-logger 打印⽇志记录协助本地调试
    安装redux-logger
    npm install redux-logger --save

store.js

import {createStore,applyMiddleware} from 'redux'
import logger from 'redux-logger'
import thunk from 'redux-thunk'
const firstReducer=(state=0,action)=>{
  console.log(action)
  switch(action.type){
    case 'add':
      return state+1;
    case 'reduce':
      return state-1;
    default:
      return state;
  }
}
//创建数据仓库,把编写的reducer作为参数传入createStore
//注意:logger最好放在最后,日志最后输出才不会出bug,因为中间件按顺序执行
const store=createStore(firstReducer,applyMiddleware(thunk,logger))
export default store

6.6 抽离出reducer和action
新建count.redux.js文件存放我们抽离出的reducer和action

count.redux.js

const firstReducer = (state = 0, action) => {
  console.log(action)
  switch (action.type) {
    case 'add':
      return state + 1
    case 'reduce':
      return state - 1
    default:
      return state
  }
}
const add = () => ({ type: 'add' })
const reduce = () => ({ type: 'reduce' })
const asyncAdd = () => dispatch => {
  setTimeout(() => {
    dispatch({ type: 'add' })
  }, 1000)
}
export { firstReducer, add, reduce, asyncAdd }

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import * as serviceWorker from './serviceWorker'
import { Provider } from 'react-redux'
import { firstReducer } from './count.redux'
import { createStore, applyMiddleware } from 'redux'
import logger from 'redux-logger'
import thunk from 'redux-thunk'

const store = createStore(firstReducer, applyMiddleware(thunk, logger))

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)
serviceWorker.unregister()

App.js

import './App.css'
import { Button } from 'antd'
import React, { Component } from 'react'
import { connect } from 'react-redux'
import {add,reduce,asyncAdd} from './count.redux'

@connect(
  state => ({ count: state }),
 {add,reduce,asyncAdd}
)
class App extends Component {
  render() {
    return (
      <div>
        <h1>redux累加器</h1>
        {this.props.count}
        <div>
          <Button onClick={() => this.props.add()}>加一</Button>
          <Button onClick={() => this.props.reduce()}>减一</Button>
          <Button onClick={() => this.props.asyncAdd()}>延迟加一</Button>
        </div>
      </div>
    )
  }
}
export default App
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

uncle_Huang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值