爱编程

RN(四)--组件间通信

2018-01-03  本文已影响88人  doudo

谈组件通信前我们先了解一下组件的生命周期,这也是基础。

一、组件生命周期

我们先来看个图: 组件生命周期

这个图看上图挺乱,其实我们注意一下经常会用到的就行:

因为界面是经常变化的,render也是经常触发的。所以如果有修改数据的操作,就会多次触发,使结果难以预料。比如如果你在render中setState,就会触发render执行,而又会执行setState,导致死循环。

二、组件间通信

1. 父组件向子组件通信(子组件间通信也类似)
//代码解释:父组件初始化一个时间time,父组件显示该值,并把这个初始值传给子组件显示;然后触摸会修改父组件的time值,并同步给子组件。
//子组件
class CountDown extends Component {
  state = {
    count: this.props.defaultTime,//state可以理解为静态,只初始化一次
  };
  render() {
    const { count } = this.state;
    return (  
      <Text>子:{this.state.count}</Text>
    )
  }
  componentWillReceiveProps(nextProps){
    this.setState({
      count : nextProps.defaultTime,
    });
  }
  componentWillUnmount() {
    clearInterval(this.timer);
  }
}
//父组件
class App extends Component {
  state = {
    time : 30,
  }
  press = ()=>{
    const {time} = this.state;
    this.setState({
      time : time+10,
    })
  }
  
  render() {
    return (
      <View>
        <TouchableOpacity onPress={this.press}>
        <Text>加10秒</Text>
        </TouchableOpacity>
        
        <CountDown defaultTime={this.state.time} />{/*render刷新时,会重用该组件*/}
        <Text>父:{this.state.time}</Text>
      </View>
    )
  }
}

通过父组件通过ref将子组件的实例保存为父组件的成员变量,父组件就可以通过该成员变量直接执行子组件的方法了,可以把数据作为参数进行传递。ref后的参数即箭头函数的参数为该组件的实例。

class CountDown extends Component {
  state = {
    count: this.props.defaultTime,//state可以理解为静态,只初始化一次
  };
  render() {
    const { count } = this.state;
    return (  
      <Text>子:{this.state.count}</Text>
    )
  }
  addTime = ()=>{
    const {count} = this.state;
    this.setState({
      count : count+10,
    })
  }
}

class App extends Component {
  state = {
    time : 30,
  }
  press = ()=>{
    //父组件自身数据的修改
    const {time} = this.state;
    this.setState({
      time : time+10,
    })
    //直接调用子组件的方法
    this.countDown.addTime(10);
  }
  
  render() {
    return (
      <View>
        <TouchableOpacity onPress={this.press}>
        <Text>加10秒</Text>
        </TouchableOpacity>
        
        {/*ref后的参数为该组件的实例*/}
        <CountDown ref={ins=>this.countDown=ins} defaultTime={this.state.time} />
        <Text>父:{this.state.time}</Text>
      </View>
    )
  }
}
2. 子组件向父组件通信(回调函数)

父组件将函数作为子组件的props传递给子组件,子组件需要向父组件通信时,就调用传递过来的函数,数据作为函数的参数传回。

//子组件
class CountDown extends Component {
  state = {
    count: 5,
  };
  render() {
    const { count } = this.state;
    return (
        <Text>{count}</Text>
    )
  }
  componentDidMount() {
    this.timer = setInterval(() => {
      const { count } = this.state;
      if (count === 0) {
        this.props.timeUp && this.props.timeUp('aaa');//回调父组件的方法
        return clearInterval(this.timer);
      }
      this.setState({
        count: count - 1,
      });
    }, 1000);
  }
  componentWillUnmount() {
    clearInterval(this.timer);
  }
}
//父组件
class App extends Component {
  timeUpParent = (param)=>{
    alert('时间到,参数:是'+param);
  }
  
  render() {
    return (
      <View>
        <CountDown timeUp={this.timeUpParent} />
      </View>
    )
  }

}

如果有多个子组件都会回调那怎么办呢?
那就需要给每个子组件传个参数,不过子组件并不用显式的回传,只需传自己的要传的参数,父组件在参数中就会收到之前自己传的值。这样说可能不好理解,不要紧,看代码就好理解了。

//子组件
class CountDown extends Component {
  state = {
    count: 5,
  };
  render() {
    const { count } = this.state;
    return (
        <Text>{count}</Text>
    )
  }
  componentDidMount() {
    this.timer = setInterval(() => {
      const { count } = this.state;
      if (count === 0) {
        this.props.timeUp && this.props.timeUp('子组件传递的参数:aaa');//对于子组件来说,他要传的参数是箭头函数前边的参数
        return clearInterval(this.timer);
      }
      this.setState({
        count: count - 1,
      });
    }, 1000);
  }
  componentWillUnmount() {
    clearInterval(this.timer);
  }
}
//父组件
class App extends Component {
  arr = ['1','2','3'];
  timeUpParent = (param1,param2)=>{
    alert('时间到'+'\n'+'param1是'+param1+'\n'+'param2是'+param2);
  }
  
  render() {
    return (
      <View>
        {
        this.arr.map(i=>{
        {/*传给子组件的属性的为整个箭头函数,子组件的参数为箭头函数的参数*/}
        return <CountDown key={i} timeUp={(childParam)=>{this.timeUpParent('父用于区分子组件的参数:'+i,childParam)}} />
        })
        }
      </View>
    )
  }
}
3. 任意组件之间的通信

这些高级的东西,先暂时有个概念,知道是解决什么问题即可,先掌握以上的基础是当前之重。

上一篇下一篇

猜你喜欢

热点阅读