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 之 state 和 props 以及 redux 和 react-redux
Component 中 state 和 props 的區別; 元件Component中狀態state和屬性props的區別 state props state是在元件內部定義的一個特殊物件{},既起到元件內部的一種快取作用,也具備由於
React Native之Text控制元件屬性和樣式
屬性 numberOfLines 文字行數限制,新增後超過限制行數文字會在末尾預設以…的形式省略。 ellipsizeMode 設定文字縮略格式,配合numberOfLines使用,values: * tail:在末尾…省略(預設值) * c
React Native之Android 和 iOS在點選觸發事件時的相容性處理
最近,我在專案中遇到了一個bug,bug的情況描述大致如下: 當點選按鈕A時,彈出彈層,彈層有一個按鈕B,邏輯是:當點選按鈕B時,首先彈層消失,緊接著開始調取C介面流程。在Android上正確顯示,但是iOS中只是彈層消失,並沒有調取C介面事件。 對於這種情況,我之前開發過
react native之原生和RN的互動
前言:前端時間隨著自己的學習和研究,也寫了幾篇關於react native的文章,雖然都是比較簡的,但是都是根據自己的效果來做的流程,所以還是比較實用的,可以避免很多的坑。這篇react native
React Native之Redux動態插入reducer
RN的使用狀態管理我們使用的方式大多數有倆種,分別是redux和mobx這倆種狀態工具。那麼這次選取redux考慮一個東西---reducer的動態注入。 首先說一下背景----假如說你的app有100 reducer,而我們的store是唯一的。那麼我
React native 之android的圖示和啟動圖片
哎哎呀呀,上篇說到了react native的IOS的圖示和啟動圖片的設定,其實最主要的是尺寸!相應的尺寸設定好了以後就不會報錯了!ok~這篇說的是React native的android的圖示和啟動頁面!!!!!1.圖示:其實android的圖示設定很簡單,一般情況下只需要替換就可以了(當然你也可以不去替換
React Native之內部方法常用幾種寫法和呼叫規則
1 簡單部分程式碼 export default class App extends Component<Props> { render() { return (
React-Native之Xcode虛擬機器快捷鍵重新整理和彈出選單不能用
1:描述 有時候執行在Xcode虛擬機器上的react-native專案 command+T和command+D沒有效果 2:原因 其實這個問題主要是由於iOS Simulator和鍵盤之間斷開了連線導致的, 也就是說iOS Simulator不在接受鍵盤的事件
React Native之Redux使用詳解之Reducers(30)
React Native之Redux使用詳解之Reducers 一. Reducers Actions 描述發生了什麼,但不能指定響應中state怎麼變化,這是Reducers的工作。 1. 設計State Shape 在Redux中,所有sta
React Native之學習ListView的單選以及記錄資料
var mSelectWhat = -1; var ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); //當且僅當cell中的任意兩行不相等時才重新渲染\ export default class Desig
React Native - 3 View, Text簡介以及onPress & onLongPress事件
分享 關鍵字 添加 res com ive img src 解釋 我們要生成如下的構圖 直接上圖,不解釋。 如下圖所示,定義函數,函數之間不需要逗號,在元素上添加事件,使用關鍵字this.{function name}
React Native之Touchable四組件
width font clas 容易 原生 ber 支持 cit out 一、TouchableHighlight 概念: 本組件用於封裝視圖,使其可以正確響應觸摸操作。當按下的時候,封裝的視圖的不透明度會降低,同時會有一個底層的顏色透過而被用戶看到,使得視圖變暗或變亮。
React Native之登錄界面的布局
處理器 圖片 blank 轉載 圓角 print extends cit hit 版權聲明:本文為博主原創文章,未經博主允許不得轉載。 代碼註釋比較詳細 /** * Sample React Native App * https://github.com/fa
react native中的聊天氣泡以及timer封裝成的發送驗證碼倒計時
日常 per pad direct 總結 mage str parent erb 今天看來情書寫的文章,研究了一下大佬寫的文章,自己做一點總結。 其實,今天我想把我近期遇到的坑都總結一下:1.goBack的跨頁面跳轉,又兩種方法,一可以像兔哥那樣修改navigatio
react-native之遠程圖片修改後APP不更新
reactnative react-native react native 刷新圖片 base64今天在做客戶的項目時,有一個需求是App上要顯示遠端的圖片,而遠端的圖片有可能會更新,但圖片名不變。在react-native中,顯示圖片是用的自帶的Image組件,大家都知道react在更新組件之前都會判斷pr
ES之值類型以及堆和棧
以及 span arc nic ont 一個 永遠 cti 方式 ES的數據類型: 原始類型(值存在棧內存中): Number、String Boolean、undefined、null charAt(inde
使用WebStorm開發React-native之基礎
ttr regexp 渲染 hang reg 路徑 tostring png text 配置問題: (1)找不到SDK路徑,或者沒有SDK對應的版本:SDK必須是android-23才可以(更新SDK) 解決方法:環境變量,必須設置Android_HOME
React Native的state使用詳解
red 什麽 style data return javascrip ets pre fault 什麽是State props是不可改變,只讀的。為了實現交互,就需要用到組件的state。我們將組件看為狀態機,UI是各種各樣的狀態,並在各種各樣的狀態之間可以切換,只需要改
react-native之模擬器調試
adb div connect oid native 令行 input 模擬 key 手動觸發搖一搖:adb shell input keyevent 82(有時模擬器搖一搖無效) android studio檢測不到模擬器: 命令行cd到模擬器安裝目錄,找到adb.exe
React Native之this詳解
過程 show super try this registry alert item rop this引起的錯誤詳解 我們在學習React Native的過程中,肯定經常遇見過undefined is not an object這樣的問題吧,尤其是剛開始學習的