React尚硅谷103-114(react-redux,优化redux,devtools,纯函数)

react-redux

yarn add redux
yarn add react-redux
开发者工具:yarn add redux-devtools-extension

  1. 两个概念:

    • UI组件不能使用任何redux的api,只负责页面呈现和交互等

    • 容器组件,负责和redux通信,将结果交给UI组件

      1. 如何创建容器组件————靠react-redux的connect函数
        • connect(mapStateToProps,mapDispatchToProps)(UI组件)
        • mapStateToProps:映射状态,返回值是一个对象
        • mapDispatchToProps:映射操作状态的方法,返回值是一个对象
  2. 备注:容器组件中的store是靠props传进去的,不是在容器组件中直接引入

  3. 和redux区别:多一层容器组件,删除原来UI组件关于redux的方法

    容器组件:

import CountUI from '../../components/Count'
import {createIncrementAction,createDecrementAction,createIncrementAsyncAction} from '../../redux/count_action'
// 引入store,别自己引入,靠父组件传
// import store from '../../redux/store'
//引入connect,使用connect创建并暴露一个Count容器组件
import {connect} from 'react-redux'
//a函数的返回的对象作为状态传递给了UI组件
//第一个参数为函数(1)redux中所保存的状态
function mapStateToProps(state){
    return {count:state}
}
// (1)用于操作状态的方法
function mapDispatchToProps(dispatch) {
    return {
        // 通知redux执行加法
        jia:number=>dispatch(createIncrementAction(number)),
        // 通知redux执行减法
        jian:number=>dispatch(createDecrementAction(number)),
        jiaAsync:(number,time)=>dispatch(createIncrementAsyncAction(number,time)),
    }
}

export default connect(mapStateToProps,mapDispatchToProps)(CountUI)//connect返回值也是一个函数,然后调用

UI组件:

import React, { Component } from 'react'
//为了获取状态
export default class Count extends Component {
    state={carname:'奔驰c63'}
    increment = () => {
        const { value } = this.selectNumber;
        this.props.jia(value*1)
    }
    decrement = () => {
        const { value } = this.selectNumber;
        this.props.jian(value*1)
    }
    incrementIfOdd = () => {
        const { value } = this.selectNumber;
        if(this.props.count%2!==0){
            this.props.jia(value*1)
        }
    }
    incrementAsync = () => {
        const { value } = this.selectNumber;
        this.props.jiaAsync(value*1,500)
    }


    render() {
        //ui组件接收到的props
        // console.log(this.props)
        return (
            <div>
                <h1>当前求和为:{this.props.count}</h1>
                &nbsp;<select ref={c => this.selectNumber = c}>
                    <option value="1">1</option>
                    <option value="2">2</option>
                    <option value="3">3</option>
                </select>&nbsp;
                <button onClick={this.increment}>+</button>&nbsp;
                <button onClick={this.decrement}>-</button>&nbsp;
                <button onClick={this.incrementIfOdd}>当前求和为奇数再加</button>&nbsp;
                <button onClick={this.incrementAsync}>异步加</button>&nbsp;
            </div>
        )
    }
}

容器组件简写:react-redux底层做dispatch处理,传mapDispatchToProps对象

import CountUI from '../../components/Count'
import { createIncrementAction, createDecrementAction, createIncrementAsyncAction } from '../../redux/count_action'
import { connect } from 'react-redux'
// const mapStateToProps=state=> ({count: state })
// function mapDispatchToProps(dispatch) {
//     return {
//         jia: number => dispatch(createIncrementAction(number)),
//         jian: number => dispatch(createDecrementAction(number)),
//         jiaAsync: (number, time) => dispatch(createIncrementAsyncAction(number, time)),
//     }
// }

export default connect(
    state => ({ count: state }),
    {
        jia: createIncrementAction,
        jian: createDecrementAction,
        jiaAsync: createIncrementAsyncAction
    }
)(CountUI)

index.js简化

1.
//不引入store
//store.subscribe注释
2.使用Provider的时候
import store from './redux/store'
import {Provider的时候} from 'react-redux'
ReactDOM.render(
  <BrowserRouter>
    <Provider store={store}>
      <App />
    </Provider>
  </BrowserRouter>,
  document.getElementById('root')
);

容器组件和UI组件组成一个文件,container

手写一个container练习连接redux

import React, { Component } from 'react'
import { createIncrementAction } from '../../redux/count_action'
import { connect } from 'react-redux'
class Count extends Component {
    add = () => {
        this.props.jia(1)
    }

    render() {
        return (
            <div>
                <button onClick={this.add}>点我加一</button>
                <div>数值:{this.props.he}</div>
            </div>
        )
    }
}
export default connect(
    state => ({ he: state })
    ,
    {
        jia: createIncrementAction
    }
)(Count)

多个reduces的时候,使用combineReducers

//store.js:
import {createStore,applyMiddleware,combineReducers} from 'redux'
import countReducer from './reducers/count.js'
import personReducer from './reducers/person.js'
//引入redux-thunk,可以dispatch函数
import thunk from 'redux-thunk'
// 总的reducer
const allReducer = combineReducers({
    he:countReducer,
    rens:personReducer
})
export default createStore(allReducer,applyMiddleware(thunk))
//Person.jsx组件:
import React, { Component } from 'react'
import {nanoid} from 'nanoid'
import {connect} from 'react-redux'
import {addCreateAction} from '../../redux/actions/person'
class Person extends Component {
    addPerson = () => {
        const name = this.nameNode.value;
        const age = this.ageNode.value;
        const personObj = {id:nanoid(),name,age}
        this.props.add(personObj)
    }
    
    render() {
        console.log(this.props)
        return (
            <div>
                <hr />
                <h2>我是person组件</h2>
                <input ref={c=>this.nameNode=c} type="text" placeholder="输入名字"/>
                <input ref={c=>this.ageNode=c} type="text" placeholder="输入年龄"/>
                <button onClick={this.addPerson}>添加</button>
                <ul>
                    {/* <li>{this.props.person.name}--年龄1</li> */}
                    {
                        this.props.person.map(ele=>{
                            return (
                                <li key={ele.id}>{ele.name}--{ele.age}</li>
                            )
                        })
                    }
                    <li>{this.props.count}</li>
                </ul>
            </div>
        )
    }
}
export default  Person = connect(
    // 因为是总状态
    state=>({person:state.rens,
        count:state.he})
    ,
    {add:addCreateAction}
)(Person)

reducer.js中需要纯函数

  1. 同样的输入,必得到同样的输出(返回)
  2. 不得改写参数数据
  3. 不会产生副作用,如网络请求,输入输出设备
  4. 不能Data.now()或者Math.random()

redux开发者工具

  1. yarn add redux-devtools-extension

  2. store中配置

    import {composeWithDevTools} from ‘redux-devtools-extension’

    const store = creteStore(allReducer,composeWithDevTools(applyMiddleWare(thunk)))

把汇总reducers放在reducers文件夹暴露给store

// 汇总reducer,不要在store中引入
import {combineReducers} from 'redux'
import countReducer from './count.js'
import personReducer from './person.js'
export default  combineReducers({
    he:countReducer,
    rens:personReducer
})
//store.js
import {createStore,applyMiddleware} from 'redux'
import allReducer from './reducers/index.js'
//引入redux-thunk,可以dispatch函数
import thunk from 'redux-thunk'
import {composeWithDevTools} from 'redux-devtools-extension'
export default createStore(allReducer,composeWithDevTools(applyMiddleware(thunk)))

多触发对象简写方式

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值