因为他们三者实际使用中可能会有或多或少的联系,为了便于理解和后续的使用,这里先拥挤一下,写到一块儿,方便查看,这里分解介绍 状态机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(父)
又粘出来了,能够本身测试一下他们的顺序哈