【two】React之 组件之间的通讯、props的深入、组件生命周期、render-props和高阶组件

1. 使用props组件通讯

父组件->子组件

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

子组件->父组件

  1. 父组件提供回调函数。用于接收数据
  2. 将该函数作为属性值,传递给子组件
  3. 子组件通过props调用回调函数
import React from 'react';
import ReactDOM from 'react-dom';
class Parent extends React.Component {
  state = {
    data: ''
  }

  //父组件提供回调函数
  getChilfMsg = data => {
    console.log("接受子组件传递的数据", data)
    this.setState({
      data: data
    })

  }
  render() {
    return (
      <div>
        这是父组件:
        {this.state.data}
        <Child getMsg={this.getChilfMsg}></Child>
      </div>)
  }
}
class Child extends React.Component {
  state = {
    msg: '我是子组件'
  }
  handleClick = () => {
    //子组件调用父组件中传递的回调函数
    this.props.getMsg(this.state.msg)
  }
  render() {
    return (
      <div>
        这是子组件:
        <button onClick={this.handleClick}>点击</button>
      </div>)
  }
}



//渲染组件
ReactDOM.render(<Parent></Parent>, document.getElementById('root'))
兄弟组件
  1. 提供一个组件作为这两个兄弟组件的父组件
  2. 通过父组件->子组件通讯的方式进行通讯

2.使用Context跨越多层组件传值

const { Provider, Consumer } = React.createContext()

class AAl extends React.Component {
  render() {
    return (
     <Provider value="我是符组件的值">
        <div>
          这是父组件:
          <Ac></Ac>
        </div>
      </Provider>
     )
  }
}
const Ac=props=>{
  return(
    <Consumer>
    {data => <span>dsdasdas {data}</span>}
  </Consumer>

  )
}
//渲染组件
ReactDOM.render(<AAl/>, document.getElementById('root'))

3.props深入

Children属性

  • 表示组件标签的子节点,当组件标签有子节点时,props就会有该属性
  • 值可以是任意值(文本、React元素、组件、 函数)
//可以是标签
ReactDOM.render(<Parent><p>我是子节点</p></Parent>, document.getElementById('root'))
//可以是函数
ReactDOM.render(<Parent>{() => { console.log("函数子节点") }}</Parent>, document.getElementById('root'))
  • 通过props.children调用

props的校验

  • 允许在创建组件时,就指定props的类型、格式等

  • 可以捕获使用组件时导致的错误

  • 使用校验步骤
    1.安装prop-types
    npm i prop-types

    2.导入prop-types包

    3.使用组件名.propTypes={}来给组件的props添加校验规则

    4.校验规则通过导入的prop-types对象向来指定

import React from 'react';
import ReactDOM from 'react-dom';
//	2.导入prop-types包
import type from 'prop-types'
const Acs = props => {
  const App = props.colors
  const list = App.map((item, index) => <li key={index}>{item}</li>)
  return (

    <ul>{list}</ul>
  )
}
//3.使用  组件名.propTypes={} 来给组件的props添加校验规则
Acs.propTypes={
//4.指定校验规则
  colors: type.array
}

//渲染组件
ReactDOM.render(<Acs colors={[1,2]}></Acs>, document.getElementById('root'))
约束规则
  • 常见类型 arry、bool、func、number、object、string
  • 必填项可以使用isRequired来限制
  • 指定结构的对象可以使用shape({ })
props默认值

通过组件名.defaultProps来设置默认值
在未传入props时生效

Acs.defaultProps={
  colors:[1,2]
}

4.组件生命周期

只有类组件才有生命周期

生命周期的三个阶段

创建阶段
  • 执行时机:页面加载时
  • 执行顺序
    constructor()->render()->componetDidMount
钩子函数触发时机
constructor创建组件时,最先执行
render每次组件渲染时都会触发
componetDidMount组件挂载结束后
更新阶段

更新阶段也就是执行**render()**渲染页面的时候。

  • 执行时机:
    1.执行setState()
    2.执行firceUpdate()
    3.组件接受到新的props
  • 执行顺序
    render()->componetDidUpdate

注意在componetDidMount中如果要调用setState()更新状态,必须要放到一个if条件中。条件是判断前后数据内容是否一致

原因调用setState()会调用render()重新渲染页面,render()执行结束后又会调用componetDidMount。在componetDidMount里面仍然调用了setState(),导致递归调用。

卸载阶段

通过componetWillUnmount在组件从页面消失时。执行清理操作

5.render-porps和高阶组件

使用render-props模式实现获取鼠标坐标

import React from 'react';
import ReactDOM from 'react-dom';
import type from 'prop-types'
class Mouse extends React.Component {
  state = {
    x: 0,
    y: 0
  }
  move = e => {
    this.setState({
      x: e.clientX,
      y: e.clientY
    })
  }
  componentDidMount() {
    window.addEventListener('mousemove', this.move)
  }
  render() {
    return (
      //使用children属性
      this.props.children(this.state)
      //使用render属性
     // this.props.render(this.state)
    )
  }
}
//校验必须又children
Mouse.propTypes={
  chileren:type.func.isRequired
}
class App extends React.Component {
  render() {
    return (
      <div>
      //使用render属性实现
        {/* <Mouse render={mouse=>{return <p>x:{mouse.x}y:{mouse.y}</p>}}></Mouse> */
        
		//使用children属性实现
          <Mouse>
            {
              mouse => {
                return <p>x:{mouse.x}y:{mouse.y}</p>
              }
            }

          </Mouse>

        }
      </div>
    )
  }
}

//渲染组件
ReactDOM.render(<App ></App>, document.getElementById('root'))

高阶组件的使用

  1. 创建一个函数,名称约定以with开头
  2. 指定函数参数,参数应该以大写字母开头(作为要渲染的组件)
  3. 在函数内部创建一个类组件,提供复用的状态逻辑代码,并返回
  4. 在该组件中,渲染参数组件,同时将状态通过prop传递参数组件
  5. 调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中
import React from 'react';
import ReactDOM from 'react-dom';
import type from 'prop-types'

function WithMouse(Wrapped) {
//在函数内部创建一个类组件,提供复用的状态逻辑代码,并返回
  class Mouse extends React.Component {
    state = {
      x: 0,
      y: 0
    }
    move = e => {
      this.setState({
        x: e.clientX,
        y: e.clientY
      })
    }
    componentDidMount() {
      window.addEventListener('mousemove', this.move)
    }
    //在该组件中,渲染参数组件,同时将状态通过prop传递参数组件
    render() {
      return <Wrapped {...this.state}></Wrapped>
    }

  }
  return Mouse
}

//测试高阶组件
const Position = props => {
  return (<p>
    x:{props.x},y:{props.y}
  </p>)

}
//获取增强后的组件
// 调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中
const MousePosition = WithMouse(Position)


class App extends React.Component {
  render() {
    return (<div>
      <h1>高阶</h1>
      <MousePosition></MousePosition>
    </div>
    )
  }
}

//渲染组件
ReactDOM.render(<App></App>, document.getElementById('root'))

displayName属性

用于设置调试信息。给函数中的类组件设置名字

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

圆○

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值