react-native 之 state 和 props 以及 redux 和 react-redux
Component 中 state 和 props 的區別;
元件Component中狀態state和屬性props的區別
state | props |
---|---|
state是在元件內部定義的一個特殊物件{} ,既起到元件內部的一種快取作用, 也具備由於state變化而激發生命週期中渲染的方法 render()被回撥的作用。且使用域僅限於元件內部。 |
props是元件屬性,連線了外部父元件和元件內部的使用域。 它的改變激發宣告週期方法componentWillReceiveProps(nextProps) 和渲染的方法render()逐次被回撥。連線外部父元件, 可以通過父元件向其傳遞value、function等,連線內部元件, this.props快取了當前元件的所有props屬性內容 即 {value, function}=this.props; |
程式碼解釋 props
/**
* 通過封裝 FlatList 自定義一個列表元件
*/
export default class MyFlatList extends Component {
constructor(props) {
super(props);
}
...
/**
*象元件FlatList中的
*ref、ListHeaderComponent、ItemSeparatorComponent、
*data、keyExtractor、onRefresh、refreshing等都是props屬性;
*
* 象這種樣式的定義 this.props.itemSeparator、
* this.props.onRefresh、this.props.refreshing、this.props.onLoadMore等
* 屬於自定義元件MyFlatList的屬性,是我們依照FlatList所定義的。
* 類似象外部開放的介面一樣,就像這裡FlatList使用自己的
* 屬性ListHeaderComponent、ItemSeparatorComponent、data等一樣來使用;
* @returns {XML}
*/
render() {
return (<View style={{flex: 1, backgroundColor: Colors.bg}}>
<FlatList
ref={(flatlist) => this.flatlist = flatlist}
ListHeaderComponent={this._header}
renderItem={this._renderItem}
ItemSeparatorComponent={this.props.itemSeparator}
data={this.props.data}
keyExtractor={this._keyExtractor}
onRefresh={this.props.onRefresh}
refreshing={this.props.refreshing}
onEndReachedThreshold={0.1}
onEndReached={this.props.onLoadMore}
initialNumToRender={3}
getItemLayout={(data, index) => ({
length: 250, offset: (250 + 10) * index, index
})}
/>
</View>);
}
}
這是使用MyFlatList,來看下它的這個props
export default class FlatlistScreen extends Component {
...
/**
*這裡MyFlatList的 itemSeparator、data、onRefresh 、refreshing 、onLoadMore
*就是FlatList中使用this.props.xxx來定義的。
* @returns {XML}
*/
render() {
return (<View style={styles.container}>
...
<MyFlatList
{...this.props}
itemSeparator={() => this.separator()}
data={this.state.dataSource}
onRefresh = {()=>this.onRefresh()}
refreshing = {this.state.isRefresh}
onLoadMore = {()=>this.onLoadMore()}
/>
</View>);
}
}
除了以上,如果是對資料內容的props屬性的變化,如上面程式碼的data變化,必然會激發MyFlatList元件生命週期方法componentWillReciveProps回撥,這裡我們可以在render方法回撥前,對資料再次進行判斷處理。
**這就是props屬性功能和作用!!**
程式碼解釋 state
export default class FlatlistScreen extends Component {
constructor(props) {
super(props);
this.unmount = false;
this.state = ({
dataSource : [],
isRefresh: true,
});
}
...
/**
* 功能:使用箭頭函式,不使用bind;因為bind函式每呼叫一次就會建立一個新的函式
*/
onRefresh() {
this.setState({
isRefresh: true,
});
//功能:製造重新整理效果
this.interval = setInterval(() => {
clearInterval(this.interval);
//功能:製造上拉載入更多的效果
const data = [];
for (let i = 0; i < 8; i++) {
data.push({id: i, title: '親子旅遊日帶娃兒玩' + i + '折起', state: '已過期', date: '2018/06/0' + (i - 8)},)
}
this.setState({
dataSource: data,
isRefresh: false,
});
}, 2000)
}
...
render() {
return (<View style={styles.container}>
...
<MyFlatList
{...this.props}
itemSeparator={() => this.separator()}
data={this.state.dataSource}
onRefresh = {()=>this.onRefresh()}
refreshing = {this.state.isRefresh}
onLoadMore = {()=>this.onLoadMore()}
/>
</View>);
}
}
看構造方法這裡
this.state = ({
dataSource : [],
isRefresh: true,
});
這就是state的定義方式。通過改變dataSource、isRefresh的值就能激發render再次渲染元件。
比如這裡的onRefresh方法使用了
this.setState({
dataSource: data,
isRefresh: false,
});
來控制改變state的時機,來控制元件渲染的時機。
**這就是狀態state的使用!!**
react-native 與 Redux 的配合使用;
在Redux使用中,一些必知的概念
Redux | state | action | reducers |
---|---|---|---|
Redux 是 JavaScript 狀態容器, 提供可預測化的狀態管理。 使用 Redux 的一個益處, 就是它讓 state 的變化過程變的可預知和透明。 |
以一個物件樹的形式儲存在於一個單一的 store 中, 惟一改變 state 的辦法是觸發 action。 |
一個描述發生什麼的指示器物件。 action 內必須使用一個字串型別的 type 欄位, 來表示將要執行的動作。 且應該儘量減少在 action 中傳遞的資料; |
描述 action 如何改變 state 樹。 reducer 就是一個純函式,接收舊的 state 和 action,返回新的 state。 |
這裡是我基於Redux實現的已給簡單操作流程原始碼
結合原始碼+圖例,分析下redux的執行操作流程,解讀redux是怎樣原理!
登入操作執行圖
現在定位在登入頁面,處於未登入狀態,需要點選登入操作。
圖並結合原始碼分析
登入頁面的部分原始碼,展示了登入頁面的UI
從原始碼中50行看到,點選登入按鈕,則呼叫方法login()
,而login()這個方法是從this.props
中解構賦值拿出來的,就是原始碼37行所示。
疑問1? this.props
中的login()是從哪裡來的,怎麼會在this.props中?!
接著看同一js檔案中的程式碼片段
這裡有一個方法非常的重要connect()
,她是幹什麼的,這裡可以解答。
簡單的說是,就我們所看到的程式碼從64到74行,connect()裡面有兩個回撥函式,第一個回撥的是state(Login頁面的state),第二回撥的是dispatch(Login頁面用來進行分發登入操作的Action)。通過connect()()
實現了 回撥函式中 status、isSuc、user 和 login() 他們與當前的元件(登入頁面)的this.props繫結,也就是他們被注入到了this.props中。
所以,點選登入的執行流程是這樣的:
點選登入按鈕——>呼叫this.props中的login方法——>派發登入操作的action ——>.. reducer處理…導致store的state樹中登入元件的state發生變化 … ——>原始碼中65行執行回撥,同時UI將會執行重新的重新整理、渲染——>渲染過程中需要的內容,從回撥中的state中獲取、賦值。
繼續深入…
登入功能的Action中有兩類內容,一是需要傳遞的使用者資料物件
二是派發的Action構建函式
圖中可以清晰看到,Action有兩種實現方式,其中最後一種是非同步的Action構建函式,前面則是同步的Action構建函式;通常非同步的Action中會呼叫同步的Action。而同步的Action有一個特點就是有一個約定成俗的欄位叫type,標識著Action的通知型別。
當執行登入操作,使用redux進行登入操作的action進行派發的時候,呼叫了非同步的Action,非同步的通知由在內部執行非同步操作,呼叫同步的action。執行到這裡,action就會被分發到哪裡呢??reducer
reducer也分為兩部分,一是登入頁面內容展示登入元件的state
是一個登入操作在執行到reducer時的處理,進行復制、賦值、填充的state模型的資料物件,store樹中的一個物件。
reducer的處理也很簡單,就是根據action的指定處理方式type,進行處理。處理完成之後,返回一個新的state物件。看原始碼是不是這樣的?!
執行處理到這裡,想到你已經發起疑問了。疑問2?總覺得,到reducer處理之後與元件容器那兒回撥,直到頁面再次渲染,沒有什麼關聯??!它們到底是怎麼建立關係的呢?
當然是通過Redux,以及處理非同步action需要用到的中介軟體(標準的做法是使用 Redux Thunk 中介軟體)。
看這裡,首先是集合管理action的處理,對reducer的管理
然後把對reduer的管理,以及處理結果再交給redux
並且也同時,把上面的兩個reduer對應的處理結果state,作為store樹的分支,繫結到了store中,進行統一管理和處理。而且還有一點很關鍵、很重要!也是急需解決的重要疑問——store樹長什麼樣子??
經過我的實踐和測試對比得出結論,
store樹
中的登入元件的state,其資料內容的樣子是和上圖中原始碼第10行
rootReduer
中的資料結構LoginIn是對應的。也就是說他們是互相對映的。即,
store與rootReduer
在資料結構上是一致的,
store樹
就是通過這樣的
rootReduer
中一條條
{key:value}
資料拼湊到一起所組成的物件。
如果有點疑問,自己可以動手試一試,並用下圖再加深下印象
store樹是用來管理元件state資料的,好,因為我們使用了全域性提供store的方式進行了處理,
store中的屬性,我們可以在專案中進行全域性使用。
所以,在connect()()
程式碼塊中,當state發生變化,產生回撥,我們可以通過state.LoginIn.status、state.LoginIn.isSuc、state.LoginIn.user來指定拿到當前元件對應的state資料。而state.LoginIn的呼叫方式就是從store樹中取出LoginIn對應的state,而LoginIn是哪來的?也許內容有點多,蒙圈了,其實就在原先這裡第11行程式碼。
所以,我之前總結的結論,store樹中的登入元件的state,其資料內容的樣子是和上圖中原始碼第10行
rootReduer
中的資料結構LoginIn是對應的。也就是說他們是互相對映的。
store與rootReduer 在資料結構上是一致的, store樹 就是通過這樣的rootReduer 中一條條 {key:value} 資料拼湊到一起所組成的物件。
是正確的!到這裡則回答了上面的疑問2?,同時也解決了Redux的使用以及執行原理。
相關文章
- React-Native入門(3) this、props和state使用React
- React 入門-redux 和 react-reduxReactRedux
- redux 和 react-redux 部分原始碼閱讀ReduxReact原始碼
- React 深入系列3:Props 和 StateReact
- [譯] 深入理解 Props 和 State
- 深入解析React props和state屬性React
- react-redux的Provider和connectReactReduxIDE
- React-redux的原理以及簡單使用ReactRedux
- react、redux、react-redux之間的關係ReactRedux
- react設定預設state和預設propsReact
- react-redux 學習以及模組化配置方案ReactRedux
- react-reduxReactRedux
- 實操《深入淺出React和Redux》第四期–react-reduxReactRedux
- react-redux(二)ReactRedux
- 深入理解redux之從redux原始碼到react-redux的原理Redux原始碼React
- Vuex之state和gettersVue
- redux && react-redux原始碼解析ReduxReact原始碼
- React Native基礎之props,state,styleReact Native
- react-redux 的使用ReactRedux
- React-redux基礎ReactRedux
- react-redux 進階ReactRedux
- React Native 探索(三)元件的 Props (屬性) 和 State (狀態)React Native元件
- react-redux/redux相關API,用法原理ReactReduxAPI
- 對React、Redux、React-Redux詳細剖析ReactRedux
- 帶你瞭解redux與react-reduxReduxReact
- 小白路程之----初學React語法棧之redux與react-reduxReactRedux
- react-redux的基本用法ReactRedux
- React-Redux簡單使用ReactRedux
- react-redux原始碼解析ReactRedux原始碼
- React-Redux原始碼分析ReactRedux原始碼
- props設定state誤區
- Redux 入門教程(3):React-Redux 的用法ReduxReact
- Redux 入門教程(三):React-Redux 的用法ReduxReact
- react-redux的淺比較ReactRedux
- react-redux實踐總結ReactRedux
- react-redux學習筆記ReactRedux筆記
- 揭開redux,react-redux的神祕面紗ReduxReact
- React-Redux進階(像VUEX一樣使用Redux)ReactReduxVue