React入门七: 组件通讯

716 阅读3分钟

这是我参与8月更文挑战的第六天,活动详情查看:8月更文挑战

1.组件通讯介绍

组件是独立且封闭的单元,默认情况下只能使用组件自己的数据。 在组件化过程中,我们将一个完整的功能拆分成多个组件,以便更好地完成整个应用的功能。但多个组件之间避免不了要共享数据,所以要打破独立封闭性,这个过程就是组件通讯。

2.props

2.1 props基本使用

  • 组件是封闭的 要接收外部数据应该通过props实现
  • props的作用:接收传递给组件的数据
  • 传递数据: 给组件标签添加属性
<Hello name="jack" age={19}/>
  • 接收数据:函数组件通过参数props接收数据,类组件通过this.props接收数据

函数组件

function Hello(props){
	return (
	 <div>接收到数据:{props.name}</div>	
	)
}

类组件

class Hello extends React.Component{
	render(){
		return(
		 <div>接收到的数据:{this.props.age}</div>
		)
	}
}

例子1 : 函数组件 我们打印出的props是一个对象

//2  接收数据
const Hello = props =>{
  console.log(props)
  return(
    <div>
      <h1>props:{props.name}</h1>
    </div>
  )
}

// 1 传递数据
ReactDOM.render(<Hello name="jack" />, document.getElementById('root'))

例子2 :类组件

//2  接收数据
class Hello extends React.Component{
  render(){
    console.log(this.props)
    return(
      <div>
        <h1>props:{this.props.name}</h1>
      </div>
    )
  }
}

// 1 传递数据
ReactDOM.render(<Hello name="jack" />, document.getElementById('root'))

2.2 props特点

  • 可以给组件传递任何类型
// 字符型
<Hello age="19"/>
// 数值型
<Hello age={10}/>
// 数组
<Hello colors=['red','green','pink']/>
// 函数
<Hello fn={()=>console.log('this is 函数')}/>

在函数组件中传递函数 是能够调用组件中传递的函数的 props.fn()

const Hello = props =>{
  props.fn()
  return(
    <div>
      <h1>props:{props.name}</h1>
    </div>
  )
}
// 1 传递数据
ReactDOM.render(<Hello name="jack" fn={()=>console.log('this is 函数')} />, document.getElementById('root'))

在类组件中

class Hello extends React.Component{
  constructor(props){
    super(props)
    props.fn()
  }
  render(){
    console.log(this.props.fn);
    return(
      <div>
        <h1>props:{this.props.name}</h1>
      </div>
    )
  }
}

// 1 传递数据
ReactDOM.render(<Hello name="jack" fn={()=>console.log('this is 函数')} />, document.getElementById('root'))

传递 jsx

<Hello name="jack" 
tag = {<p>这是一个标签</p>}
fn={()=>console.log('this is 函数')} />, document.getElementById('root'))
  • props是只读的对象,只能读取属性的值,无法修改对象。修改后会报错
const Hello = props =>{
  props.fn()
  props.name="sssss"
  return(
    <div>
      <h1>props:{props.name}</h1>
      {props.tag}
    </div>
  )
}

在这里插入图片描述

  • 注意:使用类组件时,如果写了构造函数,应该将props传递给super(),否则,无法在构造函数中或获取到props
class Hello extends React.Component{
	constructor(props){
	 // 推荐将props传递给父类构造函数
		super(props)
		 //console.log(this.props)
		 //console.log(props)
	}
	render(){
		console.log(this.props)
		return <div>{this.props.age}</div>
	}
}

3. 组件通讯得三种方式

3.1 父组件传递给子组件

  1. 父组件提供要传递的state数据
  2. 给子组件添加属性,值为state中的数据
  3. 子组件中通过props 接收父组件中传递的数据
class Parent extends React.Component{
  state={
    lastName:"wang"
  }
  render(){
    return(
      <div style={{background:"red"}}>
        父组件:
        <Child name={this.state.lastName}/>
      </div>
    )
  }
}
const Child = (props)=>{
  console.log(props)
  return(
    <div style={{background:"skyblue"}}>
      <p>子组件:{props.name}</p>
    </div>
  )
}
// 1 传递数据
ReactDOM.render(<Parent/>, document.getElementById('root'))

3.2 子组件传递数据给父组件

思路:利用回调函数,父组件提供回调,子组件调用,将要传递的数据作为回调函数的参数

  1. 父组件提供一个回调函数(用于接收数据)
  2. 将该函数作为属性的值,传递给子组件
  3. 子组件通过props调用回调函数
  4. 将子组件的数据作为参数传递给回调函数
/**
 -  父组件
 */
class Parent extends React.Component{
  state ={
    parentMsg : ''
  }
  // 提供回调函数 接收数据
  getData = (data)=>{
    console.log("接受的数据",data)
    this.setState({parentMsg:data})
  }
  render(){
    return(
      <div style={{background:"red"}}>
        父组件:{this.state.parentMsg}
        <Child getData={this.getData}/>
      </div>
    )
  }
}
/**
 -  子组件
 */
class Child extends React.Component{
  state ={
    childMsg :'react'
  }
  handelClick = ()=>{
    this.props.getData(this.state.childMsg)
  }
  render(){
    return(
      <div style={{background:"skyblue"}}>
         <button onClick={this.handelClick}>按钮</button>
      </div>
    )
  }
}

3.3 兄弟组件

  • 将 共享状态 提升到最近的公共父组件中,由公共父组件 管理这个状态 在这里插入图片描述

  • 思想:状态提升

  • 公共父组件职责:1.提供共享状态 2.提供操作共享状态的方法

  • 要通讯的子组件只需要通过props接收状态或操作状态的方法

class Counter extends React.Component {
  // 提供共享状态
  state ={
    count:0
  }
  // 提供修改状态的方法
  Add = ()=>{
    this.setState({
      count:this.state.count+1
    })
  }
  render() {
    return (
      <div>
        <Child1 count={this.state.count}/>
        <Child2 Add={this.Add}/>
      </div>
    )
  }
}
const Child1 = (props) => {
  return <h1>计数器:{props.count}</h1>
}
const Child2 = (props) => {
  return <button onClick={()=>{props.Add()}}>+1</button>
}

ReactDOM.render(<Counter />, document.getElementById('root'))