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

react

本文部分内容参考阮一峰的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) 的全部内容, 来源链接: utcz.com/z/382492.html

回到顶部