react-redux之connect方法

connect簡介

react-redux僅有2個API,Provider和connect,Provider提供的是一個頂層容器的作用,實現(xiàn)store的上下文傳遞。

原理解析

首先connect之所以會成功,是因為Provider組件:

在原應(yīng)用組件上包裹一層,使原來整個應(yīng)用成為Provider的子組件

接收Redux的store作為props,通過context對象傳遞給子孫組件上的connect

那connect做了些什么呢?

它真正連接 Redux 和 React,它包在我們的容器組件的外一層,它接收上面 Provider 提供的 store 里面的 state 和 dispatch,傳給一個構(gòu)造函數(shù),返回一個對象,以屬性形式傳給我們的容器組件。

connect(mapStateToProps, mapDispatchToProps, mergeProps, options = {})

connect作用:連接React組件與 Redux store。

connect真正連接的是容器型組件,容器型組件主要關(guān)注業(yè)務(wù)邏輯的處理,比如從服務(wù)器拉取數(shù)據(jù),進(jìn)行數(shù)據(jù)校驗等,容器組件處理好的數(shù)據(jù)再通過props傳遞給需要使用的展示型組件,展示型組件是關(guān)注界面渲染的組件。

一個應(yīng)用(或頁面)中可以有多個容器型組件,這取決于你的業(yè)務(wù)邏輯復(fù)雜程度,一般最外層的組件是會做為一個容器組件進(jìn)行connect(但這不是必須),當(dāng)你層級較低的組件中有較多業(yè)務(wù)邏輯需要處理時,往往也會在它的上一層封裝一個容器組件專門處理這些邏輯,這時這個組件也是會被connect的。

使用 connect() 前,需要先定義 mapStateToProps 這個函數(shù)來指定如何把當(dāng)前 Redux store state 映射到展示組件的 props 中。例如,VisibleTodoList 需要計算傳到 TodoList 中的 todos,所以定義了根據(jù) state.visibilityFilter 來過濾 state.todos 的方法,并在 mapStateToProps 中使用。

const getVisibleTodos = (todos, filter) => {
  switch (filter) {
    case 'SHOW_COMPLETED':
      return todos.filter(t => t.completed)
    case 'SHOW_ACTIVE':
      return todos.filter(t => !t.completed)
    case 'SHOW_ALL':
    default:
      return todos
  }
}

const mapStateToProps = state => {
  return {
    todos: getVisibleTodos(state.todos, state.visibilityFilter)
  }
}

除了讀取 state,容器組件還能分發(fā) action。類似的方式,可以定義 mapDispatchToProps() 方法接收 dispatch() 方法并返回期望注入到展示組件的 props 中的回調(diào)方法。例如,我們希望 VisibleTodoListTodoList 組件中注入一個叫 onTodoClick 的 props ,還希望 onTodoClick 能分發(fā) TOGGLE_TODO 這個 action:

const mapDispatchToProps = dispatch => {
  return {
    onTodoClick: id => {
      dispatch(toggleTodo(id))
    }
  }
}

最后,使用 connect() 創(chuàng)建 VisibleTodoList,并傳入這兩個函數(shù)。

import { connect } from 'react-redux'

const VisibleTodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)

export default VisibleTodoList

connect和@connect的區(qū)別

The @ symbol is in fact a JavaScript expression currently proposed to signify decorators:

Decorators make it possible to annotate and modify classes and properties at design time.

Here's an example of setting up Redux without and with a decorator:

Without a decorator

import React from 'react';
import * as actionCreators from './actionCreators';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

function mapStateToProps(state) {
  return { todos: state.todos };
}

function mapDispatchToProps(dispatch) {
  return { actions: bindActionCreators(actionCreators, dispatch) };
}

class MyApp extends React.Component {
  // ...define your main app here
}

export default connect(mapStateToProps, mapDispatchToProps)(MyApp);

Using a decorator

import React from 'react';
import * as actionCreators from './actionCreators';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

function mapStateToProps(state) {
  return { todos: state.todos };
}

function mapDispatchToProps(dispatch) {
  return { actions: bindActionCreators(actionCreators, dispatch) };
}

@connect(mapStateToProps, mapDispatchToProps)
export default class MyApp extends React.Component {
  // ...define your main app here
}

From What's the '@' (at symbol) in the Redux @connect decorator?

為什么我們需要react-redux?

熟悉redux的人可能知道,redux是數(shù)據(jù)存儲和管理的工具,但是想要在react中使用redux,并不能直接將store、action和react組件建立連接,所以就需要react-redux來結(jié)合react和redux。

Redux 的工作流程,Reducer 的拆分

從何處開始解析react-redux源碼?

1、在JavaScript中,讀懂別人的代碼文件,你首先應(yīng)該看的是函數(shù)的入口。

2、找到函數(shù)入口,然后看有哪些參數(shù)。

3、看看導(dǎo)入了哪些額外的插件,每個插件的作用大概預(yù)測一下。

4、進(jìn)入函數(shù)體進(jìn)行解讀。

如何發(fā)送網(wǎng)絡(luò)請求

當(dāng)我們需要從服務(wù)器獲取數(shù)據(jù)時,我們應(yīng)該在組件的哪一個生命周期方法中發(fā)送網(wǎng)絡(luò)請求呢?React官網(wǎng)上提到,可以在componentDidMount中發(fā)送網(wǎng)絡(luò)請求,這也是一般情況下的最佳實踐。有些人也會把發(fā)送網(wǎng)絡(luò)請求放在componentWillMount中,并且認(rèn)為這個方法先于componentDidMount調(diào)用,所以可以更快地獲取數(shù)據(jù)。個人認(rèn)為,這種使用方法一般也是沒有問題的,但在一些場景下會出現(xiàn)問題,比如需要在服務(wù)器端渲染時,componentWillMount會被調(diào)用兩次,一次是在Server端,一次是在Client端。可參考這篇文章。

詳見

  1. React系列——react-redux之connect方法解析
  2. 用好React,你必須要知道的事情
  3. 關(guān)于react-redux中的connect用法介紹及原理解析
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容