React Native学习总结第三天

495 阅读4分钟

1.0 组件的生命周期

  • render中只做与渲染有关的操作,只读取、不修改任何数据(临时变量除外)

    • 因为界面的更改是经常的,所以render是经常触发的

    • 所以如果你有修改数据等操作,就会多次触发,使结果难以预料

    • 比如你执行setState,那么setState又触发render,就会导致死循环

  • 随组件加载只执行一次的操作,放在WillMount或者DidMount中

    • 比如远程取首页数据(fetch),比如弹出提示框
  • 记得在WillUnmount中销毁定时器和一些订阅事件

  • props发生变化,使用WillReceiveProps来处理(比如将变动同步给state)

      componentWillReceiveProps(nextProps){
              this.setState({
               
                count:nextProps.time,
              })
            }
    
    
    import React, { Component } from 'react'
    	import {
    	 AppRegistry,
    	 StyleSheet,
    	 Text,
    	 View,
    	} from 'react-native'
    
    
    	//这里写一个定时器组件 在ES5中需要导入第三方的定时器类
    		class CountDown extends Component {
    	 	state ={
    		count : 5,
    	};
    		render(){
    			const { count } = this.state;
     			 return <View> {count > 0 && <Text>{count}</Text>} </View>
    }
    	//组件已经加载成功
    	 componentDidMount(){
    		 this.timer = setInterval(() => {
    		  const { count } = this.state;
      			if (count === 0) {
        			return clearInterval(this.timer);
     		 }
     			 this.setState({
       			 count: count - 1,
     		 });
    		}, 1000);
    	 }
    	 	////组件即将销毁 释放内存
    		componentWillUnmount() {
    			clearInterval(this.timer);
    	}	
    }
    
    
    	class App extends Component {
    		 	render() {
    		 	 return (
    		  		 <View style={styles.container}>
    		   		 <Text style={styles.welcome}>
      		  			 <CountDown />
        		</Text>
      			</View>
    			)
    		}
    	}
    
    
    
    	const styles = StyleSheet.create({
    		 container: {
    		 flex: 1,
    		 backgroundColor: '#F5FCFF',
    		},
    
    	})
    
    AppRegistry.registerComponent('App', () => App)
    
    

2.0 组件间通信(重点,难点)

  • 父组件向子组件通信、子组件之间通信 (子控件调用父控件的函数或者属性 都是需要带入this.props.属性名或者函数名)

    • 1.父组件以自身的state作为子组件的props;父组件调用setState,于是子组件的props相应变化 (说明:Component中若使用state而不是props渲染,则需使用componentWillReceiveProps生命周期)
    • 通过ref调用子组件的方法
    • 写法1:推荐
    class App extends Component {
      	render() {
      		return (
    				<CountDown ref={
     			 instance => this.countDown = instance
      		 } />
      	 )  
      }
      	  componentDidMount() {
         this.countDown.add(10086);
       }
    }
    
    
    	 * 写法2:老式写法
    
    class App extends Component {
      render() {
      	return (
      	 <CountDown ref=“countDown”/>
      	)  
      }
      componentDidMount() {
      	this.refs.countDown.add(10086);
    }
    }	
    

    下面是demo代码

import React, { Component } from 'react'
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
} from 'react-native'

//编写定时器组件
class CountDown extends Component {
  state ={
    count : 30,
  }
   render(){
     const {count}=this.state;
     return (
        <Text>{count}</Text>
     )
   }
  add = (time) =>{
    this.setState({
      count:this.state.count+time,
    })
  }
  
  
  componentDidMount(){
    this.timer=setInterval(()=>{
      const { count } =this.state;
      if (count == 0){
        return clearInterval(this.timer);
      }
      this.setState({
        count :count - 1,
      })
    },1000)
  }
  componentWillUnmount(){
    clearInterval(this.timer);
  }
}
class App extends Component {
  //es6的函数写法 addTime是方法名 ()参数名   =>{}执行的方法体
  addTime = () =>{
    this.a.add(10);
    
  }
  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress ={this.addTime}>
          延迟10秒
        </TouchableOpacity>
        <Text style={styles.welcome}>
          {/*
            <CountDown  ref={q => this.countDown = q}
            如何理解这句代码:CountDown是当前的组件类 q表示CountDown组件类的实例 q是实例的名字a 可以理解oc的 Person *p =[Person new];
            => 表示作用于的意思 我们都知道要想界面能够进行刷新 只能对当前的属性进行setState操作 所以刷新界面 只能对当前的属性进行操作,属性的变化
            变化就会引起界面的变化 所以用this.a 对q的植进行接收
          */}
          <CountDown  ref={q =>this.a = q}/>
        </Text>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
})

AppRegistry.registerComponent('App', () => App)

  • 子组件向父组件通信
  • 父组件将函数作为props传递给子组件,子组件在需要时调用,将数据作为函数参数传回(此谓之“回调”(callback). 下面的例子是带参数传递
	import React, { Component } from 'react'
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
} from 'react-native'

//编写定时器组件
class CountDown extends Component {
  state ={
    count : 5,
  }
   render(){
     const {count}=this.state;
     return (
        <Text>{count}</Text>
     )
   }
timeup =() => {
  alert('时间到!');
  this.props.timeupParent && this.props.timeupParent(123);
}
  
  
  componentDidMount(){
    this.timer=setInterval(()=>{
      const { count } =this.state;
      if (count == 0){
        this.timeup();
        return clearInterval(this.timer);
      }
      this.setState({
        count :count - 1,
      })
    },1000)
  }
  componentWillUnmount(){
    clearInterval(this.timer);
  }
}
class App extends Component {
  
  timeupParent = (params) => {
    alert('我知道了'+params);
  }
  
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
            {/*this.timeupParent与this.timeupParent()的区别
            this.timeupParent()表示函数的直接调用
            this.timeupParent 表示传的参数
            */}
          <CountDown  timeupParent={this.timeupParent} />
        </Text>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
})

AppRegistry.registerComponent('App', () => App)


![](/Users/jiangpeng/Desktop/2018-01-19 13_52_54.gif)

  • 动态列表的回调函数参数(重点:难以理解的是语法)

	import React, { Component } from 'react'
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
} from 'react-native'

//编写定时器组件
class CountDown extends Component {
  state ={
    count : 2,
  }
   render(){
     const {count}=this.state;
     return (
        <Text>{count}</Text>
     )
   }
timeup =() => {
  //alert('时间到!');
  //子控件调用父控件的函数或者属性 都是需要带入this.props.属性名或者函数名
  this.props.a && this.props.a('子组件的参数' +12312312);
}
  
  
  componentDidMount(){
    this.timer=setInterval(()=>{
      const { count } =this.state;
      if (count == 0){
        this.timeup();
        return clearInterval(this.timer);
      }
      this.setState({
        count :count - 1,
      })
    },1000)
  }
  componentWillUnmount(){
    clearInterval(this.timer);
  }
}
class App extends Component {
  
  timeupParent = (param1,param2) => {
   alert('我知道了' +param1);
   alert('我知道了' +param2);
  }
  
  state = {
    arr:['张三'],
  }
  
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          {
            this.state.arr.map(i =>{
              {/*如何理解:<CountDown key={i} timeupParent={(child) => this.timeupParent('父组件的参数' +i,child)}/>
                this.timeupParent('父组件的参数' +i,child)表示调用函数
              */}
              return <CountDown key={i} a={(child) => this.timeupParent('父组件的参数' +i,child)}/>
            })
          }
        </Text>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
})

AppRegistry.registerComponent('App', () => App)