connect簡介
react-redux僅有2個(gè)API,Provider和connect咧纠,Provider提供的是一個(gè)頂層容器的作用钝吮,實(shí)現(xiàn)store的上下文傳遞迷雪。
原理解析
首先connect之所以會(huì)成功载矿,是因?yàn)镻rovider組件:
在原應(yīng)用組件上包裹一層垄潮,使原來整個(gè)應(yīng)用成為Provider的子組件
接收Redux的store作為props,通過context對象傳遞給子孫組件上的connect
那connect做了些什么呢闷盔?
它真正連接 Redux 和 React魂挂,它包在我們的容器組件的外一層,它接收上面 Provider 提供的 store 里面的 state 和 dispatch馁筐,傳給一個(gè)構(gòu)造函數(shù),返回一個(gè)對象坠非,以屬性形式傳給我們的容器組件敏沉。
connect(mapStateToProps, mapDispatchToProps, mergeProps, options = {})
connect作用:連接React組件與 Redux store。
connect真正連接的是容器型組件,容器型組件主要關(guān)注業(yè)務(wù)邏輯的處理盟迟,比如從服務(wù)器拉取數(shù)據(jù)秋泳,進(jìn)行數(shù)據(jù)校驗(yàn)等,容器組件處理好的數(shù)據(jù)再通過props傳遞給需要使用的展示型組件攒菠,展示型組件是關(guān)注界面渲染的組件迫皱。
一個(gè)應(yīng)用(或頁面)中可以有多個(gè)容器型組件,這取決于你的業(yè)務(wù)邏輯復(fù)雜程度辖众,一般最外層的組件是會(huì)做為一個(gè)容器組件進(jìn)行connect(但這不是必須)卓起,當(dāng)你層級(jí)較低的組件中有較多業(yè)務(wù)邏輯需要處理時(shí),往往也會(huì)在它的上一層封裝一個(gè)容器組件專門處理這些邏輯凹炸,這時(shí)這個(gè)組件也是會(huì)被connect的戏阅。
使用 connect()
前,需要先定義 mapStateToProps
這個(gè)函數(shù)來指定如何把當(dāng)前 Redux store state 映射到展示組件的 props 中啤它。例如奕筐,VisibleTodoList
需要計(jì)算傳到 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)方法。例如誊爹,我們希望 VisibleTodoList
向 TodoList
組件中注入一個(gè)叫 onTodoClick
的 props 蹬刷,還希望 onTodoClick
能分發(fā) TOGGLE_TODO
這個(gè) action:
const mapDispatchToProps = dispatch => {
return {
onTodoClick: id => {
dispatch(toggleTodo(id))
}
}
}
最后,使用 connect()
創(chuàng)建 VisibleTodoList
频丘,并傳入這兩個(gè)函數(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ù)存儲(chǔ)和管理的工具迂卢,但是想要在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)入了哪些額外的插件日麸,每個(gè)插件的作用大概預(yù)測一下寄啼。
4、進(jìn)入函數(shù)體進(jìn)行解讀代箭。
如何發(fā)送網(wǎng)絡(luò)請求
當(dāng)我們需要從服務(wù)器獲取數(shù)據(jù)時(shí)墩划,我們應(yīng)該在組件的哪一個(gè)生命周期方法中發(fā)送網(wǎng)絡(luò)請求呢?React官網(wǎng)上提到梢卸,可以在componentDidMount中發(fā)送網(wǎng)絡(luò)請求走诞,這也是一般情況下的最佳實(shí)踐。有些人也會(huì)把發(fā)送網(wǎng)絡(luò)請求放在componentWillMount中蛤高,并且認(rèn)為這個(gè)方法先于componentDidMount調(diào)用蚣旱,所以可以更快地獲取數(shù)據(jù)。個(gè)人認(rèn)為戴陡,這種使用方法一般也是沒有問題的塞绿,但在一些場景下會(huì)出現(xiàn)問題,比如需要在服務(wù)器端渲染時(shí)恤批,componentWillMount會(huì)被調(diào)用兩次异吻,一次是在Server端,一次是在Client端喜庞【骼耍可參考這篇文章。
詳見