资讯专栏INFORMATION COLUMN

React系列之一起认识Render Prop

LMou / 349人阅读

摘要:比如有个组件,它用来实时的获取鼠标的位置。命名空间,多个修改同一个导致的命名冲突。据说源码里面为每个组件增加路由属性就是通过该方法好了大功完成了,欢迎一起讨论学习个人博客地址意卿

1.mixins

写过react项目的应该都碰到过,不同组件复用相同代码的问题,在react早期使用React.createClass创建组件的时代,我们经常使用的是mixins来实现代码复用。比如有个组件A,它用来实时的获取鼠标的位置。

//A组件
import React from "react"
import ReactDOM from "react-dom"

const App = React.createClass({
  getInitialState() {
    return { x: 0, y: 0 }
  },

  handleMouseMove(event) {
    this.setState({
      x: event.clientX,
      y: event.clientY
    })
  },

  render() {
    const { x, y } = this.state

    return (
      

The mouse position is ({x}, {y})

) } }) ReactDOM.render(, document.getElementById("app"))

如果此时有个组件B也想集成这个功能,我们可以通过mixins,代码是这样的

//B组件
import React from "react"
import ReactDOM from "react-dom"

const MouseMixin = {
  getInitialState() {
    return { x: 0, y: 0 }
  },

  handleMouseMove(event) {
    this.setState({
      x: event.clientX,
      y: event.clientY
    })
  }
}

const App = React.createClass({
  // Use the mixin!
  mixins: [ MouseMixin ],
  
  render() {
    const { x, y } = this.state

    return (
      

The mouse position is ({x}, {y})

) } }) ReactDOM.render(, document.getElementById("app"))

很容易是吧~但委屈的是react16之后就不再支持mixins了,因为es6普及了呀!


那怎么办呢?办法总是有的,HOC(高阶组件)的概念被提出来,什么是高阶组件?说白了其实就是把函数当做参数传入到另一个函数中,在我们展开高阶组件前,我们先来想想除了因为es6的普及react不再支持mixins之外,mixins还有啥其它缺点不。当然是有的,有以下几点:

难以溯源,mixins修改state,在组件内部你无法知道state从哪来,尤其是有多个mixins的情况。

命名空间,多个mixins修改同一个state导致的命名冲突。

2.HOC(高阶组件)

所以为了代替mixins,很多人就提出了HOC(高阶组件),代码是下面这样的。

import React from "react"
import ReactDOM from "react-dom"

const withMouse = (Component) => {
  return class extends React.Component {
    state = { x: 0, y: 0 }

    handleMouseMove = (event) => {
      this.setState({
        x: event.clientX,
        y: event.clientY
      })
    }

    render() {
      return (
        
) } } } class App extends React.Component{ render() { // 代替直接处理state,我们从props里获得x,y坐标 const { x, y } = this.props.mouse return (

The mouse position is ({x}, {y})

) } } //把App组件当做参数传到withMouse方法里面,在withMouse内部通过props获得x、y坐标值 const AppWithMouse = withMouse(App) ReactDOM.render(, document.getElementById("app"))

看起来很不错的样子!


但是,回到之前mixins存在的问题,我们想一想,HOC有上述的问题么?我们来看下:

难以溯源,跟mixins不同的是,我们不再纠结state的源头,我们现在要纠结的是HOC的props里提供了些啥...

命名空间的冲突,这个问题依然存在,props里属性名可能会被多个HOC重复使用。

我的天.....

3.Render Prop

幸运女神降临!
mmp,前面都是炮灰,到了划重点的时候啦!

Render Prop是个值为函数的属性,通过Render Prop,组件知道什么应该被渲染

很糊涂是不是,看代码

import React from "react"
import ReactDOM from "react-dom"
import PropTypes from "prop-types"

class Mouse extends React.Component {
  static propTypes = {
    render: PropTypes.func.isRequired
  }

  state = { x: 0, y: 0 }

  handleMouseMove = (event) => {
    this.setState({
      x: event.clientX,
      y: event.clientY
    })
  }

  render() {
    return (
      
{this.props.render(this.state)}
) } } const App = React.createClass({ render() { return (
(

The mouse position is ({x}, {y})

)}/>
) } }) ReactDOM.render(, document.getElementById("app"))

看明白了么,这里我们通过定义一个render属性,值是个函数,描述了我们想要渲染的元素,然后在子组件里面调用该render方法,再回头看下之前的两个问题,难以溯源,现在主动权在父组件上,我要什么数据你们给我拿来就行了,你们子组件各自去实现,我只要结果不要过程,因而就不存在数据来源问题,命名空间的问题也没了。好厉害~~~。
最后偷偷的告诉你们一个更厉害的,上面的render方法里面我们是直接写出了渲染x,y值,只适用于当前App组件,我们可以通过高阶组件来达到为任何组件添加该功能,代码是这样的。

const withMouse = (Component) => {
    return class extends React.Component{
        render() {
            return (
                
            )}/>
        }
    }
}

据说react-router源码里面为每个组件增加路由属性就是通过该方法!

好了!大功完成了,欢迎一起讨论学习~

个人博客地址:意卿

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/93042.html

相关文章

  • React系列---React(三)组件的生命周期

    摘要:组件装载过程装载过程依次调用的生命周期函数中每个类的构造函数,创造一个组件实例,当然会调用对应的构造函数。组件需要构造函数,是为了以下目的初始化,因为生命周期中任何函数都有可能访问,构造函数是初始化的理想场所绑定成员函数的环境。 React系列---React(一)初识ReactReact系列---React(二)组件的prop和stateReact系列---之React(三)组件的生...

    geekzhou 评论0 收藏0
  • React手稿类型检查

    摘要:类型检查是为了确保传入组件的参数正确性。通常在项目中可以使用或者来实现。示例以上内容在实现一个通用组件时非常有用。类型检查和参数默认值一起使用,保证组件的正常运行。 Typechecking With PropTypes 类型检查是为了确保传入组件的参数正确性。 通常在项目中可以使用Flow或者TypeScript来实现。 React提供了PropTypes来检查类型。 示例: imp...

    tomorrowwu 评论0 收藏0
  • React系列---React(二)组件的prop和state

    摘要:给赋值也是构造函数的工作之一。在的构造函数中,还给两个成员函数绑定了当前的执行环境,因为方式创建的组件并不自动给我们绑定到当前实例对象。我们可以利用的功能,避免判断逻辑这种充斥在构造函数之中,让代码更优。 React系列---React(一)初识ReactReact系列---React(二)组件的prop和stateReact系列---React(三)组件的生命周期 组件是React...

    Labradors 评论0 收藏0
  • 源码解析 —— Vue的响应式数据流

    摘要:下面我们会向大家解释清楚为什么这个这么重要,以及它和的响应式数据流有什么关系。源码前面铺垫这么多就是希望大家能理解接下来要讲的响应式数据流。总结讲到这里大家应该都能够明白的响应式数据流是如何实现的。 Vue、React介绍 目前前端社区比较推崇的框架有Vue 和 React,公司内部许多端都自发的将原有的老技术方案(widget + jQuery)迁移到 Vue / React上了。我...

    LuDongWei 评论0 收藏0
  • 少妇白洁系列React StateUp Pattern, Explained

    摘要:本文用于阐述模式的算法和数学背景,以及解释了它为什么是里最完美的状态管理实现。欢迎大家讨论和发表意见。 本文用于阐述StateUp模式的算法和数学背景,以及解释了它为什么是React里最完美的状态管理实现。 关于StateUp模式请参阅:https://segmentfault.com/a/11... P-State, V-State 如果要做组件的态封装,从组件内部看,存在两种不同的...

    20171112 评论0 收藏0

发表评论

0条评论

LMou

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<