因爲他們三者實際使用中可能會有或多或少的聯繫,爲了便於理解和後續的使用,這裏先擁擠一下,寫到一塊兒,方便查看,這裏分解介紹 狀態機state、父子組件、props性能優化
顧名思義狀態機就是保存狀態的裝置,在RN裏面,其實就是state,咱們能夠經過設置state和改變state裏面的值來設置和調整UI元素的變更,對於不須要變更的UI寫死便可bash
舉個例子:網絡
//構造方法 constructor裏面設置初始state
this.state= {
name: '充電寶',
gender: '未知'
}
複製代碼
//render裏面設置UI
<View>
<Text>{this.state.name}</Text>
{
this.state.gender !== '未知'
&&
<Text>{this.state.gender}</Text>
}
</View>
複製代碼
以上代碼設置完畢後,會發現界面上只顯示了一個充電寶,正常顯示函數
下面的gener是在gender不爲未知的狀況下顯示的,能夠經過其條件性的控制UI的顯隱,注意:{} 必需要有佈局
若是咱們在網絡請求完畢後,須要更新UI怎麼辦呢,以上爲例性能
通常是在componentDidMout方法裏面進行網絡請求,這裏界面初次初始化渲染成功,比較適合網絡請求,此時網絡請求完成值後只須要調用setState方法便可更新UI了,例如:學習
let result = request.fetch(params)
let name = result.name
let gender = result.gender
let age = result.age
this.setState({
name,
gender: gender,
age
})
//設置完成以後,name和gender就會根據最新值更新了,age因爲UI的xml上沒有用到,實際不會渲染的
複製代碼
經過setState方法設置成功後的變量其實就是,this.state = {} 裏面的對象,當執行完畢setState方法以後,便會對新設置的值和之前UI樹上面的值進行對比,若是不同系統會自動更新替換xml樹上的變量保存的內容,沒有的狀態值也不會影響渲染(可是會佔用狀態機控件,對比渲染時,影響渲染效率,性能優化時儘可能避免此狀況)測試
在上面能夠看到設置state的時候,有的是直接寫了一個鍵值就能夠了,有的寫上鍵值對的形式,其實,只要你上面聲明的變量名和須要渲染的變量的鍵值同樣,那麼能夠使用鍵值代替鍵值對fetch
擴展: 學習了props能夠嘗試一下,在子視圖或者別的視圖中能不能經過父視圖的引用設置父視圖的state吧,相信掌握了會對之後的進階有幫助的flex
顧名思義,就是父組件和子組件,父組件在下,子組件在上,經過flexbox佈局以及合理的使用他們的關係能夠佈局出各類各樣的UI出來,在flexbox佈局裏面相信已經瞭解到他們之間是怎麼結合佈局的
這裏介紹父子組件的傳值,正常咱們想的父子組件看到的view多是這個樣子的(這樣傳值好像不必哈)
<View>
<View type={1}></View>
</View>
複製代碼
實際多是這個樣子,實際傳值的內容多是根據當前控制器(也是他的父視圖),來傳值的
<View>
<ChildView type={this.data.type}>
<ChileView>
</View>
//這樣一個叫作type的屬性就會傳入到子視圖當中去了,而子視圖當中怎麼接收呢,這就涉及到props了
複製代碼
props即屬性,this.props本身的屬性集合,父視圖傳過來的參數(屬性),會存到子視圖props裏
子視圖中能夠經過this.props能夠獲取子視圖本身的屬性列表,若是傳入了type,那麼調用的時候能夠經過這樣獲取,父視圖也同理能夠一樣的方式獲取到本身的
let type = this.props.type
const {type, name, gender} = this.props //一次獲取多個屬性變量
複製代碼
是否是很簡單這樣就能夠傳值了,那麼子組件若是回調結果給父組件呢,方法以下
1.父視圖設置一個回調(接口或者函數),子視圖在合適的時機調用(推薦)
//fatherView
//render
render() {
return (
<ChildView onSubmit={()=>{
//父視圖設置的回調方法,快捷方法
}}> </ChildView>
//固然有潔癖也能夠也能夠這樣
<ChildView onSubmit={()=>this.submit()}> </ChildView> //推薦寫法,避免錯誤
<ChildView onSubmit={this.submit.bind(this)}> </ChildView> //也能夠這麼調用
)
}
//若是view的回調聲明onSubmit那裏沒有()=>或者調用bind(this),這裏必須這麼聲明,一個好習慣,否則調用不到這個方法
submit = () => {
}
submit () {
}
//子視圖
//render
render() {
return (
<TouchableOpacity
onPress={()=>{
this.props.onSubmit && this.props.onSubmit() //先判斷一下是否存在在調用
}}>
</TouchableOpacity>
)
}
複製代碼
2.因爲對象裏面的方法均爲public,那麼能夠經過傳遞父視圖的引用,在子視圖調用傳值
//fatherView
//render
render() {
return (
//固然有潔癖也能夠也能夠這樣
<ChildView superView={this}> </ChildView>
)
}
//若是view的回調聲明onSubmit那裏沒有()=>或者調用bind(this),這裏必須這麼聲明,一個好習慣,否則調用不到這個方法
submit = () => {
}
//子視圖
//render
render() {
return (
<TouchableOpacity
onPress={()=>{
this.superView && this.superView.submit && this.superView.submit() //先判斷一下是否存在在調用
}}>
</TouchableOpacity>
)
}
複製代碼
上面就是比較簡單易用的父子組件傳值了,以props爲媒介來完成
上面子視圖中經過傳遞父視圖引用,是否是發現也能夠拿到父視圖的props和更新state了呢,因爲方法都是public,試試去看看能不能拿到而且操做吧
屬性聲明
子控件prop若是未聲明,正常寫外面可能沒有代碼提示,正常該怎麼聲明讓外界調用更方便呢
附上實例代碼:
//默認屬性,外面沒實現裏面使用這個(這個相似於類方法)
static defaultProps={
onUpdate: f => f //意思是什麼也不執行,回調
title: '123'
}
//外面實現了裏面會發生改變
static propTypes={
onUpdate: f => f //意思是什麼也不執行,回調
title: text
}
}
複製代碼
父子組件渲染流程:
父組件:componentWillMount->render->componentDidMount
父子組件:componentWillMount(父)->componentWillMount(子)->render->componentDidMount(子)->componentDidMount(父)
又粘出來了,能夠本身測試一下他們的順序哈