(精华2020年5月24日更新) react基础篇 redux的使用和react-redux的使用

  • redux的核心api
    • createStore()
      • 创建包含指定reducer的store对象
    • store对象
      • redux库最核心的管理对象
      • 内部维护着 state reducer对象
    • 核心方法
      • getState()
      • dispatch(action)
      • subscribe
  • redux的三个核心概念
    • action
      • 标识要执行行为的对象
      • 包含两个方面的属性
        • type 标识属性 值是字符串 唯一 必要的属性
        • xxx 数据属性 值类型是任意的 可选属性
        • const action = {type:‘add’,data:2}
      • action的创建工厂
        const add = ()=>({type:‘add’,data:123})
    • reducer
      • 根据老的state 返回新的state 纯函数
      • 编码见代码
      • 注意
        • 返回一个新的状态
        • 不要修改原来的状态
    • store
      • 将state action reducer 联系在一起的对象
      • 如何得到这个对象? 见代码
      • 得到这个对象的功能是什么
        • getState() 得到state
        • dispatch(action) 分发action 触发reducer的调用 产生新的state
        • subscribe() 注册监听 当产生了新的state之后 会自动的调用

首先定义函数变量action-type.js

export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'

action.js

import {INCREMENT,DECREMENT} from './action-type'
export const increment = number => ({type:INCREMENT,number})
export const decrement = number => ({type:DECREMENT,number})

reducers.js

import {INCREMENT,DECREMENT} from './action-type'
export function counter(state=0,action){
    switch(action.type){
        case INCREMENT:
            return state + action.number
        case DECREMENT:
            return state - action.number
        default:
            return state
    }
}

combineReducers可以连接多个

import {combineReducers} from 'redux'

import {
    ADD_COMMENT,
    DELETE_COMMENT,
    RECEIVE_COMMENT
} from './action-types'
// 
const initComments = []
function comments(state=initComments,action){
    switch(action.type){
        case ADD_COMMENT:
            return [...state,action.data]
        case DELETE_COMMENT:
            return state.filter((c,index)=>index !== action.data)
        case RECEIVE_COMMENT:
            return action.data
        default :
            return state
    }
}

export default combineReducers({
    comments
})

redux下index.js中引用

import React from 'react'
import ReactDOM from 'react-dom'
import {createStore} from 'redux'
import App from './components/app'
import {counter} from './redux/reducers'
const common = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__//安装谷歌插件在浏览器调试
const store = createStore(counter,common())


const render = ()=>{
    ReactDOM.render(<App store={store}/>, document.getElementById('root'))
}
// 初始化渲染
render()

// 注册监听
store.subscribe(render)

redux页面中使用

import React, {Component} from 'react'
import * as actions from '../redux/actions'
export default class App extends Component {
  state = {
    count: 0
  }

  increment = () => {
    const num = this.refs.numSelect.value*1
    this.props.store.dispatch(actions.increment(num))
  }

  decrement = () => {
    const num = this.refs.numSelect.value*1
    this.props.store.dispatch(actions.decrement(num))
  }

  incrementIfOdd = () => {
    let count = this.state.count
    if(count%2==1) {
      this.props.store.dispatch(actions.increment(count))
    }
  }

  incrementAsync = () => {
    const num = this.refs.numSelect.value*1
    setTimeout(() => {
      this.props.store.dispatch(actions.increment(num))
    }, 1000)
  }

  render () {
    return (
      <div>
        <p>
          click {this.props.store.getState()} times {' '}
        </p>
        <select ref="numSelect">
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>{' '}
        <button onClick={this.increment}>+</button>{' '}
        <button onClick={this.decrement}>-</button>{' '}
        <button onClick={this.incrementIfOdd}>increment if odd</button>{' '}
        <button onClick={this.incrementAsync}>increment async</button>
      </div>
    )
  }
}

下面介绍react-redux的使用
app.js

import React, {Component} from 'react'
import {connect} from 'react-redux'
import Counter from '../components/counter'
import {increment,decrement} from '../redux/actions'
export default connect(
  state=>({count:state}),
  {
    increment,
    decrement
  }
)(Counter)

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import {createStore} from 'redux'
import {Provider} from 'react-redux'
import App from './container/app.js'
import {counter} from './redux/reducers'
import {composeWithDevTools} from 'redux-devtools-extension'
// const common = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
const store = createStore(counter,composeWithDevTools())


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

页面中使用

import React, {Component} from 'react'
export default class Counter extends Component {
  increment = () => {
    const num = this.refs.numSelect.value*1
    this.props.increment(num)
  }

  decrement = () => {
    const num = this.refs.numSelect.value*1
    this.props.decrement(num)
  }

  incrementIfOdd = () => {
    const num = this.refs.numSelect.value*1
    let count = this.props.count
    if(count%2==1) {
        this.props.increment(num)
    }
  }

  incrementAsync = () => {
    const num = this.refs.numSelect.value*1
    setTimeout(() => {
        this.props.increment(num)
    }, 1000)
  }

  render () {
    return (
      <div>
        <p>
          click {this.props.count} times {' '}
        </p>
        <select ref="numSelect">
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>{' '}
        <button onClick={this.increment}>+</button>{' '}
        <button onClick={this.decrement}>-</button>{' '}
        <button onClick={this.incrementIfOdd}>increment if odd</button>{' '}
        <button onClick={this.incrementAsync}>increment async</button>
      </div>
    )
  }
}

redux的异步使用
改写上面的action.js

import {INCREMENT,DECREMENT} from './action-type'
export const increment = number => ({type:INCREMENT,number})
export const decrement = number => ({type:DECREMENT,number})
//异步用法
export const incrementAsync = number => {
    return dispatch =>{
        setTimeout(()=>{
            dispatch(increment(number))
        },2000)
    }
}

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import {createStore,applyMiddleware} from 'redux'
import {Provider} from 'react-redux'
import App from './container/app.js'
import {counter} from './redux/reducers'
import {composeWithDevTools} from 'redux-devtools-extension'
import thunk from 'redux-thunk'//异步
// const common = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
const store = createStore(
    counter,
    composeWithDevTools(applyMiddleware(thunk))//加上中间件配合异步
)
ReactDOM.render(<Provider store={store}>
    <App />
</Provider>, document.getElementById('root'))

app.js

import React, {Component} from 'react'
import {connect} from 'react-redux'
import Counter from '../components/counter'
import {increment,decrement,incrementAsync} from '../redux/actions'
export default connect(
  state=>({count:state}),
  {
    increment,
    decrement,
    incrementAsync
  }
)(Counter)

页面使用

import React, {Component} from 'react'
export default class Counter extends Component {
  increment = () => {
    const num = this.refs.numSelect.value*1
    this.props.increment(num)
  }

  decrement = () => {
    const num = this.refs.numSelect.value*1
    this.props.decrement(num)
  }

  incrementIfOdd = () => {
    const num = this.refs.numSelect.value*1
    let count = this.props.count
    if(count%2==1) {
        this.props.increment(num)
    }
  }

  incrementAsync = () => {
    const num = this.refs.numSelect.value*1
    this.props.incrementAsync(num)
  }

  render () {
    return (
      <div>
        <p>
          click {this.props.count} times {' '}
        </p>
        <select ref="numSelect">
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
        </select>{' '}
        <button onClick={this.increment}>+</button>{' '}
        <button onClick={this.decrement}>-</button>{' '}
        <button onClick={this.incrementIfOdd}>increment if odd</button>{' '}
        <button onClick={this.incrementAsync}>increment async</button>
      </div>
    )
  }
}

猜你喜欢

转载自blog.csdn.net/weixin_41181778/article/details/106319502