React:快速上手(5)——掌握Redux(2)

2023-08-24,,

React:快速上手(5)——掌握Redux(2)

本文部分内容参考阮一峰的Redux教程。

React-Redux原理

React-Redux运行机制

  我觉得这张图清楚地描述React-Redux的运行机制:

  React-Redux将组件划分为两类,第一类是UI组件:

只负责 UI 的呈现,不带有任何业务逻辑
没有状态(即不使用this.state这个变量)
所有数据都由参数(this.props)提供
不使用任何 Redux 的 API

  比如,我们的实例计数器就是一个UI组件,我们只写了UI的呈现规则,并且所有数据都是由this.props提供:

class Counter extends React.Component{
render() {
const{onSubmitClick,value} = this.props;
return(
<div>
<span>{value}</span>
<button onClick={onSubmitClick}>提交</button>
</div>
)
}
}

  第二类组件是容器组件:

负责管理数据和业务逻辑,不负责 UI 的呈现
带有内部状态
使用 Redux 的 API

  不过,React-Redux 规定,所有的 UI 组件都由用户提供,容器组件则是由 React-Redux 自动生成

Connect负责从UI组件生成容器组件

  如下,一行语句,我们就将获得由UI组件得到的容器组件

const CounterApp = connect(mapStateToProps,mapDispatchToProps)(Counter)

  这个函数由两个参数,mapStateToProps和mapDispatchToProps构成。它们主要定义业务逻辑,前者负责输入逻辑,即容器组件如何将state转换为props交给UI组件,来供容器组件进行UI渲染后者负责输出逻辑,用来建立 UI 组件的参数到store.dispatch方法的映射

  如下,我们定义mapStateToProps,它将state中的count字段取出映射到value属性,然后交给UI组件:

function mapStateToProps(state) {
return{
value:state.count
}
}

  然后,我们定义mapDispatchToProps,他将store.dispatch方法映射到onSubmitClick属性上,这样UI组件通过props.onSubmitClick,就可以间接调用store.dispatch,实现状态更新。

function mapDispatchToProps(dispatch) {
return{
onSubmitClick:()=>dispatch({type:'INCREASE'})
}
}

<Provider>组件

  connect方法生成容器组件以后,需要让容器组件拿到state对象,才能生成 UI 组件的参数。一种解决方法是将state对象作为参数,传入容器组件。但是,这样做比较麻烦,尤其是容器组件可能在很深的层级,一级级将state传下去就很麻烦。

  React-Redux 提供Provider组件,可以让容器组件拿到state

import { Provider } from 'react-redux'
import { createStore } from 'redux'
import todoApp from './reducers'
import App from './components/App' let store = createStore(todoApp); render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)

 上面代码中,Provider在根组件外面包了一层,这样一来,App的所有子组件就默认都可以拿到state了。

一个完整的计数器例子

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import { Provider, connect } from 'react-redux' // React component
class Counter extends Component {
render() {
const { value, onIncreaseClick } = this.props
return (
<div>
<span>{value}</span>
<button onClick={onIncreaseClick}>Increase</button>
</div>
)
}
} Counter.propTypes = {
value: PropTypes.number.isRequired,
onIncreaseClick: PropTypes.func.isRequired
} // Action
const increaseAction = { type: 'increase' } // Reducer
function counter(state = { count: 0 }, action) {
const count = state.count
switch (action.type) {
case 'increase':
return { count: count + 1 }
default:
return state
}
} // Store
const store = createStore(counter) // Map Redux state to component props
function mapStateToProps(state) {
return {
value: state.count
}
} // Map Redux actions to component props
function mapDispatchToProps(dispatch) {
return {
onIncreaseClick: () => dispatch(increaseAction)
}
} // Connected Component
const App = connect(
mapStateToProps,
mapDispatchToProps
)(Counter) ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)

  

React:快速上手(5)——掌握Redux(2)的相关教程结束。

《React:快速上手(5)——掌握Redux(2).doc》

下载本文的Word格式文档,以方便收藏与打印。