1.組件
react-redux把組件分為兩類:UI組件和容器組件。
UI組件的特征:
- 只負責 UI 的呈現,不帶有任何業務邏輯
- 沒有狀態(即不使用this.state這個變量)
- 所有數據都由參數(this.props)提供
- 不使用任何 Redux 的 API
下面展示一個UI組件:
import React,{Component} from 'react';
class Nav extends Component{
render(){
return <div>
<div>
<ul>
<li>首頁</li>
<li>發布信息</li>
<li>個人中心</li>
</ul>
</div>
</div>
}
}
容器組件的特征:
- 負責管理數據和業務邏輯,不負責 UI 的呈現
- 帶有內部狀態
- 使用 Redux 的 API
因此,UI 組件負責 UI 的呈現,容器組件負責管理數據和邏輯。
2.connect方法
react-redux提供connect()方法,從于從UI組件生成容器組件。
我使用畫圖軟件CampTools畫了connect()方法的概念圖。
connect()有四個參數:mapStateToProps、mapDispatchToProps、mergeProps和options,我們一般常用的是mapStateToProps、mapDispatchToProps這兩個參數。
connect方法在項目中的用法:
import {connect} from "react-redux";
import Login from "../components/login";
export default connect(mapStateToProps,mapDispatchToProps)(Login);
上面的代碼中,我引入了react-redux中的connect方法,Login是我引入的項目中的UI組件。connect方法接受兩個參數:mapStateToProps和mapDispatchToProps。它們定義了 UI 組件的業務邏輯。前者負責輸入邏輯,即將state映射到 UI 組件的參數(props),后者負責輸出邏輯,即將用戶對 UI 組件的操作映射成 Action。這樣就創建了一個容器組件。
3.mapStateToProps()
這個函數允許我們將store中的數據作為props綁定到組件上。
const mapStateToProps = (state)=> {
console.log('state',state);
return {
isRight:state.login.judge,
}
};
上面代碼中,mapStateToProps是一個函數,它接state作為參數,返回一個對象。這個對象有一個isRight屬性,代表UI組件的同名參數。
mapStateToProps會監聽 Store,每當state更新的時候,就會自動執行,重新計算 UI 組件的參數,從而觸發 UI 組件的重新渲染。
mapStateToProps的第一個參數總是state對象,還可以使用第二個參數,代表容器組件的props對象。
使用ownProps作為參數后,如果容器組件的參數發生變化,也會引發 UI 組件重新渲染。
connect方法可以省略mapStateToProps參數,那樣的話,UI 組件就不會監聽Store,就是說 Store 的更新不會引起 UI 組件的更新。
4.mapDispatchToProps()
connect 的第二個參數是 mapDispatchToProps,它的功能是,用來建立 UI 組件的參數到store.dispatch方法的映射。也就是說,它定義了哪些用戶的操作應該當作 Action,傳給 Store。
如果mapDispatchToProps是一個對象,它的每個鍵名也是對應 UI 組件的同名參數,鍵值應該是一個函數,會被當作 Action creator ,返回的 Action 會由 Redux發出。
const mapDispatchToProps = (dispatch) => {
return {
onJudge:(data)=>{
dispatch({type:"LOGIN",data});
}
}
};
上面的代碼中,mapDispatchToProps返回一個對象,該對象的每個鍵值對都是一個映射,定義了 UI 組件的同名參數怎樣發出 Action。
如果mapDispatchToProps是一個函數,會得到dispatch和ownProps(容器組件的props對象)兩個參數。上面的代碼寫成函數就是如下示例:
const mapDispatchToProps = (
dispatch,
ownProps
) => {
return {
onJudge: () => {
dispatch({
type: 'LOGIN',
data
});
}
};
}
想要更詳細的了解,可看項目完整代碼:https://github.com/second-Sale/second-sale