react redux基础+react-redux+redux高阶

1- redux基础

1-1 action creators

统一管理所有的action对象

// 创建数据仓库
import {createStore} from 'redux'
​
let initState = {
    name:'小白',
    age:99 
}
​
// 第一个形参: 上一次的状态
// 第二个形参: 定义的规则 {type:'changeName',name:'小黑'},{type:'changeAge',age:100}
function reducer(state=initState,action){
    switch(action.type){
        case 'changeoneName':
            return {
                ...state,
                name:action.name
            }
        case 'changeAge':
            return {
                ...state,
                age:action.age
            }
        default:
            return {
                ...state
            }
    }
}
​
​
export const actions = {
    changeName:(name)=>({type:'changeoneName',name:name}),
    changeAge:(age)=>({type:'changeAge',age})
}
​
​
let store = new createStore(reducer)
​
export default store
​
​

---one.jsx

import {actions} from '../store'
​
 change(){
        // 修改数据仓库的name
        // store.dispatch({type:'changeName',name:'小黑'})
​
        store.dispatch(actions.changeName('小蓝'))
        // this.setState({})
        console.log(store.getState());
    }

1-2 action types

统一管理所有的type

const TYPES = {
    CHANGE_NAME:'CHANGE_NAME',
    CHANGE_AGE:'CHANGE_AGE'
}
​
// 第一个形参: 上一次的状态
// 第二个形参: 定义的规则 {type:'changeName',name:'小黑'},{type:'changeAge',age:100}
function reducer(state=initState,action){
    switch(action.type){
        case TYPES.CHANGE_NAME:
            return {
                ...state,
                name:action.name
            }
        case TYPES.CHANGE_AGE:
            return {
                ...state,
                age:action.age
            }
        default:
            return {
                ...state
            }
    }
}
​
​
export const actions = {
    changeName:(name)=>({type:TYPES.CHANGE_NAME,name:name}),
    changeAge:(age)=>({type:TYPES.CHANGE_AGE,age})
}
​
​
let store = new createStore(reducer)
​
export default store
​

1-3 reducer拆分

根据功能拆分模块

---one.js

// one模块
​
let initState={
    name:'小one',
    age:'10'
}
​
const TYPES = {
    CHANGE_ONE_NAME:'CHANGE_ONE_NAME',
    CHANGE_ONE_AGE:'CHANGE_ONE_AGE'
}
​
function reducer(state=initState,action){
    switch(action.type){
        case TYPES.CHANGE_ONE_NAME:
            return {
                ...state,
                name:action.name
            }
        case TYPES.CHANGE_ONE_AGE:
            return {
                ...state,
                age:action.age
            }
        default:
            return {
                ...state
            }
    }
}
​
export const actions = {
    changeNameAction:name=>({type:TYPES.CHANGE_ONE_NAME,name}),
    changeAgeActions:age=>({type:TYPES.CHANGE_ONE_AGE,age})
}
​
export default reducer

---two.js

// one模块
​
let initState={
    name:'小two',
    age:'20'
}
​
const TYPES = {
    CHANGE_TWO_NAME:'CHANGE_TWO_NAME',
    CHANGE_TWO_AGE:'CHANGE_TWo_AGE'
}
​
function reducer(state=initState,action){
    switch(action.type){
        case TYPES.CHANGE_TWO_NAME:
            return {
                ...state,
                name:action.name
            }
        case TYPES.CHANGE_TWO_AGE:
            return {
                ...state,
                age:action.age
            }
        default:
            return {
                ...state
            }
    }
}
​
export const actions = {
    changeNameAction:name=>({type:TYPES.CHANGE_TWO_NAME,name}),
    changeAgeActions:age=>({type:TYPES.CHANGE_TWO_AGE,age})
}
​
export default reducer

---index.js

整合到一起

// 创建数据仓库
import {createStore,combineReducers} from 'redux'
​
import one from './modules/one'
import two from './modules/two'
​
// 第一个形参: 上一次的状态
// 第二个形参: 定义的规则 {type:'changeName',name:'小黑'},{type:'changeAge',age:100}
​
// 将不同不模块的reducer整合为一个
let rootReducer = combineReducers({
    one:one,
    two
})
​
let store = new createStore(rootReducer)
​
export default store

组件中使用 --- one.jsx

import React, { Component } from 'react'
import store from '../store'
// 取别名
import {actions as actionsone} from '../store/modules/one'
import {actions as actionstwo} from '../store/modules/two'
export default class One extends Component {
    componentDidMount(){
       this.uns= store.subscribe(()=>{
            // 开启监听,每次dispatch都会触发
            this.setState({})
        })
    }
    componentWillUnmount(){
        // 取消监听
        this.uns()
    }
    change(){
        // 修改数据仓库的name
        // store.dispatch({type:'changeName',name:'小黑'})
​
        // store.dispatch(actionsone.changeNameAction('小蓝'))
​
        // 修改two的name
        store.dispatch(actionstwo.changeNameAction('小绿'))
        // this.setState({})
        console.log(store.getState());
    }
    change1(){
        // 修改数据仓库的age
        // store.dispatch({type:'changeAge',age:100})
        // this.setState({})
        console.log(store.getState());
    }
    render() {
​
        console.log(store.getState());
​
        // 分模块获取状态
        let {one,two} = store.getState()
        return (
            <div className='box'>
               <h1>one组件</h1>
               <h2>数据仓库的  name---{one.name}---{two.name}</h2> 
               <h2>数据仓库的  age---{one.age}</h2> 
​
               <button onClick={()=>this.change()}>修改name</button>
               <button onClick={()=>this.change1()}>修改age</button>
            </div>
        )
    }
}
​

1-4 redux-devtools工具

1- 谷歌使用

码云--->搜索redux-devtools--> for chrome---点击 last -->下载--> 添加到扩展程序

创建数据仓库时添加

let store = new createStore(rootReducer,window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())

2- 火狐

设置---》 面向开发者扩展---> 搜索redux-devtools--->安装

2- react-redux

2-1 安装

npm i react-redux --save

2-2 使用

react-redux将组件的与数据仓库相关逻辑代码和组件视图结构分开

  • 容器型组件

    • 负责处理逻辑

    • 与数据仓库关联

    • 状态就是数据仓库

  • UI型(视图)组件

    • 主要用来显示数据

    • 与数据仓库的状态没有关联

    • 状态从props获取

2-2-1 provider

provider: 发送store

import {Provider} from 'react-redux'
import store from './store'
ReactDOM.render(
  // 发送数据仓库
  <Provider store={store}>
     <App />
  </Provider>
   ,
  document.getElementById('root')
);

2-2-2 connect

connect连接展示组件和容器组件

  • mapStateToProps: 输入逻辑,获取store的状态,返回一个对象,将数据对象传到到展示型组件中

  • mapActionsToProps: 输出逻辑,定义触发action对象来修改store的状态的方法。也要返回一个对象,将方法传到展示组件中

  • 展示组件通过props接收传递的数据

import React, { Component } from 'react'
import {connect} from 'react-redux'
import store from '../store'
// 取别名
import {actions as actionsone} from '../store/modules/one'
import {actions as actionstwo} from '../store/modules/two'

class One extends Component {
    change(){
        this.props.changeName()
    }
    change1(){
        this.props.changeAge(999)
    }
    render() {
        console.log(this.props);

        let {name,twoname,age} = this.props
        return (
            <div className='box'>
               <h1>one组件</h1>
               <h2>数据仓库的  name---{name}---{twoname}</h2> 
               <h2>数据仓库的  age---{age}</h2> 

               <button onClick={()=>this.change()}>修改name</button>
               <button onClick={()=>this.change1()}>修改age</button>
            </div>
        )
    }
}

// connect() 第一个形参
// 输入逻辑,  将数据仓库状态输入到组件中.
// 有一个默认形参,就是数据仓库的状态

let mapStateToProps = state=>{
    console.log(state,'111111');
    // 必须有返回值,就是向展示型组件(One组件)传递的数据
    return {
        name:state.one.name,
        twoname:state.two.name,
        age:state.one.age
    }
}

// 第二个形参:输出逻辑, 改变数据仓库的状态的操作
//  类似于vuex中mapActions方法。 
let mapActionsToProps = dispatch=>{
    return {
        // changeName:()=>dispatch({type:'CHANGE_ONE_NAME',name:'小红'})
        changeName:()=>dispatch(actionsone.changeNameAction('小红')),
        changeAge:(age)=>dispatch(actionsone.changeAgeActions(age))
    }
}

export default connect(mapStateToProps,mapActionsToProps)(One)


3-redux高阶

3-1 bindActionCreators

帮助我们做dispatch的操作

import {bindActionCreators} from 'redux'


// 第二个形参:输出逻辑, 改变数据仓库的状态的操作
//  类似于vuex中mapActions方法。 
let mapActionsToProps = dispatch=>{
    return {
        // changeName:()=>dispatch({type:'CHANGE_ONE_NAME',name:'小红'})
        
        // 将actionsone中的action依次定义
        // changeName:()=>dispatch(actionsone.changeNameAction('小红')),
        // changeAge:(age)=>dispatch(actionsone.changeAgeActions(age))

        // 将actionsone 的action对象同意触发
        fn:bindActionCreators(actionsone,dispatch)
    }
}

3-2 selectors

类似于计算属性,由state派发出的新得数据

---two.js

export let getTwoName = function(state){
   return state.two.name
}

export let getTwoAge = state=>state.two.ages

export let ageFor = state=>state.two.ages+'岁'

export let total = state=>state.two.list.length

---Two.jsx

// 输入逻辑
//数据的传递
let mapStateToProps = state=>{
    return {
        name:getTwoName(state),
        age:getTwoAge(state),
        agefor:ageFor(state),
        list:state.two.list,
        total:total(state)
    }
}

3-3 reselect

1- 安装

npm i reselect --save

2- 使用

定义selectors只有依赖的数据改变时才重新计算。

// 计算平均
// export let getAver = state=>{
//     console.log('计算平均数');
//     let sum = 0
//     state.one.list.forEach(item=>{
//         sum+=item.num
//     })

//     return sum/state.one.people
// }

// 通过reselect改写
//  第一个参数,所依赖的selectors
// 只有list和people改变时才重新计算
export let getAver = createSelector([getList,getPeo],(list,peo)=>{
        console.log('计算平均数');
    let sum = 0
   list.forEach(item=>{
        sum+=item.num
    })

    return sum/peo
})

3-4 redux middleware 中间件

1-自定义中间件

1- 打印

//  定义一个打印的中间件  logger
// let myLogger = function(store){
//     return function(next){
//         return function(action){
//             // 
//             console.log('本次触发的action',action);
//             console.log('改变之前的状态',store.getState());
//             next(action)
//             console.log('最新的状态',store.getState());
//             console.log('==================================');
//         }
//     }
// }
let myLogger =store=>next=>action=>{
            // 
            console.log('本次触发的action',action);
            console.log('改变之前的状态',store.getState());
            next(action)
            console.log('最新的状态',store.getState());
            console.log('==================================');
        }

2- 第三方中间件

1- redux-logger

npm i redux-logger
// 引入第三方中间件
import {logger} from 'redux-logger'

let store = new createStore(rootReducer,applyMiddleware(logger))

2- redux-thunk,能够发起异步请求

npm i redux-thunk
import thunk from 'redux-thunk'

let store = new createStore(rootReducer,applyMiddleware(logger,thunk))
export const actions = {     
    changeNameActions:name=>({type:TYPES.CHANGE_ONE_NAME,name}),
    changeAgeActions:age=>({type:TYPES.CHANGE_ONE_AGE,age}),
    changePeoActions:peo=>({type:TYPES.CHANGE_ONE_PEO,people:peo}),
    changeListActions:list=>({type:TYPES.CHANGE_ONE_LIST,list}),
    getList:()=>{
        return (dispatch)=>{
            fetch('/api/getcate').then(res=>res.json()).then(res=>{
                dispatch({type:TYPES.CHANGE_ONE_LIST,list:res.list})
            })
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值