React组件通讯

组件通讯介绍

组件是一个独立且封闭的单元,默认情况下,组件只能进行内部的数据传递。在组件化过程中,我们将一个完整的功能拆分成多个组件,以更好的完成整个应用的功能。而在这个过程中,多个组件之间不可避免的要共享某些数据。为了实现这些功能,就需要打破组件的独立封闭性,让其与外界沟通,这就叫组件通讯

组件的props

组件是封闭的,要接收外部数据需要通过props
props的作用:接收传递给组件的数据
传递数据:给组件标签添加属性
接收数据:函数组件通过参数props接收数据,类组件通过this.props接收数据

2.1 函数组件的组件通讯

通过参数props接收数据

// 2.接收数据
const Hello = props => {
  console.log(props);
  return (
    <div>
      <h1>props: {props.name} {props.age} </h1>
    </div>
  )
}
// 1.传递数据
// 将要传递的数据当做属性来写
ReactDOM.render(<Hello name='jack' age={19}/>, document.getElementById('root'))

在这里插入图片描述

2.2 类组件的组件通讯

通过this.props接收数据

// 类组件的组件通讯
class Hello extends React.Component {
  render() {
    console.log(this.props);
    return (
      <div>
        <h1>props: {this.props.name} {this.props.age} </h1>
      </div>
    )
  }

}
// 1.传递数据
ReactDOM.render(<Hello name='rose' age={19} />, document.getElementById('root'))

2.3 props的特点

可以传递任意类型的数据

函数对象,JSX都可以传递

// 2.接收数据
const Hello = props => {
  props.fn()
  return (
    <div>
      <h1>props: {props.name} {props.age}  </h1><br/>
      <h2>{props.colors}</h2><br/>
      <h2>{props.tag}</h2>
    </div>
  )
}

// }
// 1.传递数据
ReactDOM.render(
  <Hello
    name='rose'
    age={19}
    fn={() => console.log('这是一个函数对象')}
    colors={['red','pink','blue']}
    tag={<p>这是一个标签</p>}
  />,
  document.getElementById('root'))

在这里插入图片描述

props是只读的对象,只能读取属性的值,不能进行修改

给props.name赋值

  props.name = 'tom'

报错
在这里插入图片描述

使用类组件时,如果写了构造函数,应该将props传给super()

否则,将无法在构造函数中获取到props!!!

未传递props

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

ReactDOM.render( <Hello name='rose' age={19} />, document.getElementById('root'))

在这里插入图片描述
传递props 推荐使用

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

ReactDOM.render( <Hello name='rose' age={19} />, document.getElementById('root'))

在这里插入图片描述

组件通讯的三种方式

3.1 父组件传子组件

步骤
1.父组件提供要传递的state数据
2.给子组件标签添加属性,值为state中的数据
3.子组件中通过props接收父组件中传递来的数据

class Parent extends React.Component {
  state = {
    lastName: '王'
  }

  render() {
    return (
      <div className='parent'>
        父组件:
        <Child name={this.state.lastName}></Child>
      </div>
    )
  }
}

// 子组件
const Child = props => {
  console.log('子组件:',props);
  return (
    <div className="child">
      <p>子组件,接收到父组件的数据: {props.name}</p>
    </div>
  )
}
ReactDOM.render(<Parent />, document.getElementById('root'))

在这里插入图片描述

3.2 子组件传父组件

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

1.父组件提供函数getChildMsg来接收数据
2.子组件调用getChildMsg传递函数
3.调用父组件中的方法getMsg 将参数传递进去
4 父组件接收数据

// 子组件传父组件
class Parent extends React.Component {
  state = {
    parentMsg: ''
  }
  getChildMsg = msg => {
    console.log('接收到子组件的数据', msg);
    this.setState({
      parentMsg: msg
    })
  }
  render() {
    return (
      <div>
        父组件: {this.state.parentMsg}
        <Child getMsg={this.getChildMsg}/>
      </div>
    )
  }
}

// 子组件
class Child extends React.Component {
  state = { 
    msg: 'study'
   }
  handleClick = () => {
    this.props.getMsg(this.state.msg)
  }
  // 子组件通过props调用回调函数
  render() {
    return (
      <div className="child">
        子组件:<button onClick={this.handleClick}>点击,给子组件传递数据</button>
      </div>
    )
  }
}

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

在这里插入图片描述

3.3 兄弟组件

1.将共享状态提升到最近的公共父组件中,有公共父组件管理这个状态
2.思想:状态提升
3.公共父组件职责:1.提供共享状态 2.提供操作共享状态的方法
4.要通讯的子组件只需通过props接收状态或操作状态的方法

// 父组件
class Counter extends React.Component {
  // super()
  state = {
    count: 0
  }
  onIncrement = () => {
    this.setState({
      count: this.state.count + 1
    })
  }
  render() {
    return (
    <div>
      {/* 父组件中的状态通过属性传递给子组件 */}
      <Child1 count={this.state.count}/>
      <Child2 onIncrement={this.onIncrement}/>
    </div>
    )
  }
}
// 子组件中通过props接收数据
const Child1 = (props) => {
  return <h1>计数器:{props.count}</h1>
}
const Child2 = (props) => {
  return <button onClick={() => props.onIncrement()}>+1</button>
}

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

在这里插入图片描述

Context

如果两个组件嵌套多层,可以使用Context实现组件通讯
Context提供两个组件:Provider Consumer
Provider:提供数据
Consumer:消费数据


const {Provider, Consumer} = React.createContext()
class Counter extends React.Component {

  render() {
    return (
      <Provider value="rose">
        <div className='Counter'>
          <Child1 />
        </div>
      </Provider>
    )
  }
}
// 子组件中通过props接收数据
const Child1 = (props) => {
  return (
    <div className='Child1'>
      <Child2 />
    </div>
  )
}
const Child2 = (props) => {
  return (
    <div className='Child2'>
      <Child3 />
    </div>
  )
}
const Child3 = (props) => {
  return (
    <div className='Child3'>
      <Child4 />
    </div>
  )
}
const Child4 = (props) => {
  return (
    <Consumer>{data => <p>我是用Context拿来的值---{data}</p>}</Consumer>
  )
}
ReactDOM.render(<Counter />, document.getElementById('root'))

在这里插入图片描述

props深入

children属性

文本节点

const Parent = props => {
  console.log(props);
  return (
    <div>
      <h1>我是你的父组件 {props.children}</h1>
    </div>
  )
}

ReactDOM.render(<Parent>我是你的子组件--文本版本</Parent>, document.getElementById('root'))

在这里插入图片描述

JSX

const Parent = props => {
  console.log(props);
  return (
    <div>
      <h1>我是你的父组件 {props.children}</h1>
    </div>
  )
}

ReactDOM.render(<Parent><p>我是你的子组件--JSX版本</p></Parent>, document.getElementById('root'))

在这里插入图片描述

组件

const Parent = props => {
  console.log(props);
  return (
    <div>
      <h1>我是你的父组件 {props.children}</h1>
    </div>
  )
}
const Children = props => {
  return (
    <div className='Children'>
      <p>我是你的子组件--组件版本</p>
    </div>
  )
}
ReactDOM.render(<Parent>我是你的子组件--文本版本</Parent>, document.getElementById('root'))

在这里插入图片描述

props校验

对于组件来说,props是外来的,无法保证组件使用者传入什么格式的数据
==props校验:==允许在创建组件的时候,就指定props的类型、格式等
作用:捕获使用组件时因为props导致的错误,给出明确错误提示,增加代码的健壮性

步骤
1.安装prop-types (yarn add prop-types)
2.引入prop-types安装包 (import PropTypes from ‘prop-types’)
3.使用 组件名.propTypes={} 来给组件的props添加校验规则
4.校验规则通过propTypes指定

const App = props => {
  // 拿到子组件的属性
  const arr = props.colors
  const lis = arr.map((item, index) => <li key={index}>{item}</li>)

  return <ul>{lis}</ul>
}

App.propTypes = {
  colors: PropTypes.array
}

ReactDOM.render(<App colors = {['red','yello','pink']}></App>, document.getElementById('root'))

在这里插入图片描述

在这里插入图片描述

组件的生命周期

声明周期的三个阶段

创建时(挂载阶段)

执行时机:组件创建时(页面加载时)
执行顺序:constructor() -> render() -> componentDidMount

钩子函数触发时机作用
constructor创建组件时,最先执行1.初始化state 2.为事件处理程序绑定this
render每次组件调用时都会触发渲染UI(不能调用setState())
componentDidMount组件挂载(完成渲染)后1.发送网络请求 2.DOM操作

在这里插入图片描述

更新阶段

执行时机:1.New props 组件接收到新的属性 2.setState() 3.forceUpdate()
以上任意一种变化,都会导致组件重新渲染
执行顺序: render() -> componentDidUpdate() 先渲染完成,再去渲染构造函数

钩子函数触发时机作用
render每次组件调用时都会触发渲染UI(不能调用setState())
componentDidMount组件挂载(完成渲染)后1.发送网络请求 2.DOM操作 3.要用setSate 和 Ajax请求要放在if中

卸载阶段

执行时机:组件从页面中消失时

钩子函数触发时机作用
componentWillUMount组件卸载(从页面中消失)执行清理工作(清理定时器等)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值