render-props和高阶组件

港控/mmm° 2022-09-10 08:12 284阅读 0赞

render-props和高阶组件

以上两种方式都是实现状态组件复用

1.1 render props是一种模式

使用render创建复用组件

首先我们创建一个组件,这个组件里面有可以复用的方法和逻辑,下面我们写一个可以获取当前移动坐标的组件(mouse)

  1. import React, { Component } from 'react'
  2. export default class home extends Component {
  3. constructor(props) {
  4. super(props)
  5. this.state = {
  6. x: 0,
  7. y: 0
  8. }
  9. }
  10. handleMouseMove = e => {
  11. console.log(e);
  12. this.setState({
  13. x: e.clientX,
  14. y: e.clientY
  15. })
  16. }
  17. render() {
  18. return this.props.render(this.state) //将要复用的状态作为props.render(state)方法的参数,暴露到外部
  19. }
  20. componentDidMount() { //在组件挂载完成进行鼠标移动事件监听 执行handleMouseMove方法
  21. window.addEventListener('mousemove', this.handleMouseMove)
  22. }
  23. }

然后在需要该逻辑的组件中使用该组件

  1. import React, { Component } from 'react'
  2. import Home from './home'
  3. export default class asign extends Component {
  4. render() {
  5. return (
  6. <div>
  7. //传入参数mouse相当于上面暴露的this.state,在上面中组件暴露什么,那么这里接到的mouse就是什么
  8. //另外这里要注意这里一定要有返回值 因为返回的是数据状态 那么就要渲染HTML,或者null,不然就会报错
  9. <Home render={ mouse=>{ return <p>当前得位置{ mouse.x}y轴{ mouse.y}</p>}} />
  10. </div>
  11. )
  12. }
  13. }

1.2 使用children创建复用组件

注意此刻使用的是children就不是返回render 而是返回 this.props.children
复用组件的render代码

  1. render() {
  2. return this.props.children(this.state) //将要复用的状态作为props.render(state)方法的参数,暴露到外部
  3. }

父组件使用复用组件的代码

  1. <Home>
  2. { mouse => {
  3. return (
  4. <p>{ mouse}</p>
  5. )
  6. }
  7. }
  8. </Home>

使用render props模式注意要添加props校验

  1. Mouse.propTypes={
  2. children:PropTypes.func.isRequired
  3. }

如果在使用复用组件没有传递参数就会报错 因为我写的校验规则是children的属性是必填项

最后在做完所有操作之后 要特别注意一点,在react中所有使用window的方法,比如计时器,上面代码提到的鼠标监听事件,这些都是手动添加的,所以我们在组件销毁的时候一定要解绑事件,做到代码优化

  1. componentWillUnmount(){
  2. window.removeEventListener('mousemove',this.handleMouseMove)
  3. }

高阶组件

其实就是一个函数组件,接收要包装的组件,返回增强后的组件

  • 1.1 首先第一步创建一个函数,名称约定以with开头的js
    通俗来说高阶函数就好比手机套

    import React, { Component } from ‘react’
    export default function withTest(WrappedComponent) { //创建一个高阶函数以with开头,参数也必须是大写字母开头,因为我们的参数后面是当参数组件渲染的也就是,组件名由参数决定
    class test extends Component { //创建一个类组件这里面写逻辑与状态,此组件相当于手机套的核心

    1. state = {
    2. x: 0,
    3. y: 0
    4. }
    5. hanldMouseMove = e => {
    6. this.setState({
    7. x:e.clientX,
    8. y:e.clientY
    9. })
    10. }
    11. //控制鼠标状态的逻辑
    12. componentDidMount() {
    13. window.addEventListener('mousemove', this.hanldMouseMove)
    14. }
    15. //自己创建的事件手动销毁
    16. componentWillUnmount(){
    17. window.removeEventListener('mousemove', this.hanldMouseMove)
    18. }
    19. render() {
    20. //返回一个组件,这个组件就是传进来的参数是什么名字就是什么组件,比如我在外部传入test那么最终生成的组件名就是test,相当于<test {...this.state} />
    21. //...this.state,就是传入状态
    22. return <WrappedComponent { ...this.state}></WrappedComponent>
    23. }

    }
    return test //最终将这个方法返回
    }

  • 第二步 引入js并传入参数

    import React, { Component } from ‘react’
    import withTest from ‘./test’ //1.引入高阶函数
    import PropTypes from ‘prop-types’
    const Position=props=>{

    1. return ( //3.定义position的基本属性也就是传入参数的基本属性,props就是高阶函数传入的参数,在这里我们是解构state

    1. 横坐标{ props.x}
    2. 纵坐标{ props.y}


    )}
    const TestPosition = withTest(Position)//2.传入参数(Position),并且定义组件名(TestPosition )
    export default class asign extends Component {
    render() {

    1. return (
    2. <div className="home">
    3. <TestPosition></TestPosition> //4.使用组件
    4. </div>
    5. )

    }
    }

注意这样创建组件就有一个问题,那就是组件名相同,也就是手机壳的名字相同
在这里插入图片描述

为了区别组件那么就设置displayName便于区别调试时不同的组件,在react他的每个组件的命名都是通过displayName来命名的

  • 1.首先在高阶函数中添加一个名字方法

    //修改名字的方法
    function getDisplayName(WrappedComponent){
    console.log(WrappedComponent);
    return WrappedComponent.displayName ||WrappedComponent.name||’Component’
    }

打印出WrappedComponent是这个结果,使用json转换也没用,我就不过多研究,有这方面的了解可以在评论中说出来,指正,我的理解是displayName 是react的组件内置的属性,包括nameComponent
在这里插入图片描述

  • 然后在组件的返回值之前调用就行

    test.displayName=WithTest${ getDisplayName(WrappedComponent)}

完整代码
在这里插入图片描述

  • 最终生成的组件名
    在这里插入图片描述

3.高阶组件不能继续向下传递props,所以需要在高阶组件中把props一起传递给组件

在不传递props会发现在组件中是无法获取到的
在这里插入图片描述

在这里插入图片描述
但是高阶函数那边可以打印 ,说明高阶函数那边接收到了但是没有往下传,解决办法只需要将props往下传就行

在这里插入图片描述
在这里插入图片描述
这里就获取到了

发表评论

表情:
评论列表 (有 0 条评论,284人围观)

还没有评论,来说两句吧...

相关阅读

    相关 React-组件

    高阶组件是 React 中复用组件逻辑的一种技巧,高阶组件是一个函数,接收需要包装的组件,返回值为增强后的组件。 实现思路: 高阶组件内部创建一个类组件,在这个类组件中去提

    相关 组件

    什么是高阶组件? 高阶部位是一种用于复用组件逻辑的高级技术,它并不是React API的一部分。而是从React演化而来的一种模式。具体地说,高阶组件就是一个接受一个组

    相关 React组件

    高阶组件(HOC)是React里的高级技术为了应对重用组件的逻辑,HOC本质上不是React API的一部分。他是从React的组合性质中显露出来的模式 具体来说,一个高阶

    相关 React进组件

    一.介绍 1.说明: 高阶组件就是一个函数,且该函数接受一个组件作为参数,并返回一个新的组件。我的理解是定义一个A组件(函数),把这个A组件传入给B组件,B组件把A组件

    相关 react 组件

    高阶组件必须是一个函数,且必须返回一个组件,参数也必须接收一个组件 作用:能对传入的组件进行一些限定操作,可以使用生命周期等 ![在这里插入图片描述