react基础--2

2022-09-08 18:28:00 浏览数 (1)

react-redux

react-redux需要配合 redux使用,react-redux可实现 redux与react的连接

但需遵循如下规范:

1.所有UI组件都应该包裹一个容器组件,他们是父子关系

2.容器组件是真正和redux打交道的,里面可以随意使用redux的api

3.UI组件中不能使用任何redux api

4.容器组件会传给UI组件:1.redux中保存的状态,2.用于操作状态的方法

5.备注:容器给UI传递:状态、操作状态的方法,均通过props传递

基本使用

1.确保ui组件已经创建

2.创建ui组件的容器组件,用于将ui组件与redux进行连接

在容器组件键入

代码语言:javascript复制
/container/Count.jsx
// 引入 ui 组件
import CountUI from '../../components/Count' 
// 引入connect用于连接ui组件与redux
import { connect } from 'react-redux'
export default connect()(CountUI)

3.将使用UI组件的地方替换为容器组件 如在App.jsx

代码语言:javascript复制
//App.jsx
import React, { Component } from 'react'
import Count from './container/Count'
import store from './redux/store'

export default class App extends Component {
    render() {
        return (
            <div>
            // 给容器组件传入store 将ui组件与redux连接起来
            <Count store={store}>
            </div>
        )
    }
}

注意这里需要将store通过props的方式传给容器组件,而不是在容器组件里面直接引用

容器组件如何给ui组件传递状态?

需要给connect函数传递两个参数 第一个参数是给ui组件的状态,第二个参数是给ui组件的操作状态的方法 但这两个参数必须是函数,通过函数的返回值给到ui组件 如下

代码语言:javascript复制
// 引入 ui 组件
import CountUI from '../../components/Count' 
// 引入connect用于连接ui组件与redux
import { connect } from 'react-redux'

// 该函数返回的对象中的key,就是传递给ui组件的props的key
function mapStateToProps(state) {
    // state相当于 store.getState()
  return { n:state }
  // ui组件访问 this.props.n
}

function mapDispatchToProps(dispatch) {
    // dispatch 相当于 store.dispatch
    return { 
        jia:(data)=>{
        // 通知redux执行状态改变
        dispatch({type:'add', data:data})
        // UI组件直接 通过 this.props.jia(data) 执行
       }
       ... 
    }
}

export default connect(mapStateToProps,mapDispatchToProps)(CountUI)

上面的代码有点麻烦,接下来进行优化 如果使用了规范的redux可以改为下面的形式

代码语言:javascript复制
export default connect(
mapStateToProps,
{ 
    jia:createIncrementAction, // action 需新建文件定义
    jian:createDecrementAction
    ... 
}
)(CountUI)

// count_action.js
export const createIncrementAction = data => {type:'incremnt', data};

可以看到 第二个参数我们直接传了一个对象,react-redux会帮我们处理

在ui组件访问 this.props.jia this.props.jian

Provider组件使用

如果容器组件很多,那就需要传很多次store给容器组件,这里可以通过Provider解决 在index.js入口文件

代码语言:javascript复制
...
import { Provider } from 'react-redux'
import store from '../../store'
ReactDOM.render(
    <Provider store={store}>
     <App/>
    </Provider>,
    document.getElementById('root')
)

注册多个reducer

reducer用来操作本地数据 如下两个reducer

代码语言:javascript复制
// redux/reducers/person.js

const initState = [
    { id:001,name:'tome',age:18 }
]

export default function personReducer (preState=initState,action) {
    const { type,data } = action
    switch(type) {
        case 'addPerson':
            return [data,...preState]
        default:
            return preState
    }
}

// redux/reducers/count.js

const initState = 0
export defualt function countReducer(preState=initState,action ) {
    const { type, data } = action
    switch(type) {
        case 'increment':
            return preState data
        default:
            return preState
    }
}

在 store.js注册多个reducer

代码语言:javascript复制
// /redux/store.js
// combineReducers 用于注册多个reducer
import { createStore,applyMiddleware,combineReducers } from 'redux'

import countReducer from './reducers/count'
import personReducer from './reducers/person'

// 引入 redux-thunk 用于支持异步的action
import thunk from 'redux-thunk'

const allReducers = combineReducers({
    he:countReducer,
    ren:personReducer 
})
// 经过 combineReducers state变成了一个对象
// 任何容器组件都可以访问的state里面的值,实现数据共享
// 在容器组件要注意改变 取state.里面的值


//暴露store
export default createStore(allReducer,applyMiddleware(thunk))

注意 redux中的reducer函数必须是一个纯函数

也就是必须遵循 1.不得改写参数数据 2.不会产生任何副作用如网络请求 3.不能调用 Data.now()或者Math.random()等不纯方法

所以reducer不能使用 一些数组方法如 unshift,push直接对原参数进行修改 不是纯函数会影响redux对状态的改变 这样会造成数据不响应,不会更新到视图

0 人点赞