深入理解render props

作者: mytac | 来源:发表于2020-01-10 01:40 被阅读0次

前言

自己对render props\hoc\hook的区别和适用场景都不怎么了解

在写文章前的个人理解:

render props->体现组件之间的父子关系,非常灵活
hoc ->更加突出工厂模式
hooks -> 让函数组件更加贴近类组件

render props

第一次看官方文档的时候,觉得render props就是渣男制造机啊哈哈。至于为什么用“渣男”这个词来描述组件,因为“渣男”普适性高,独立性强,所以可以更好的复用,请看下方例子有更加传神的描述。

初步了解

官方例子是要实现一个这样的效果,猫随着鼠标动

demo

Mouse组件

<div className="Mouse" onMouseMove={this.handleMouseMove}>
    <p>position is ({x},{y})</p>
    <Cat x={x} y={y}/>
</div>

代码中有一个<Mouse>组件跟踪鼠标位置,将位置信息传给<Cat>,然后<Cat>组件根据Mouse传给他的信息进行显示。但是这里,Cat是Mouse的子组件,就显得不够分离了。如果你要改成狗、改成猪可以新增一个prop传图片,但是如果想鼠标经过的位置弄一些炫酷的特效,是不是就得重新写一遍获取鼠标的逻辑了~(我们设计一个组件的时候,要提高他的复用性,就要让他能处理更多的场景,所以他的功能必须更加的独立、单一,才能更好的将组件们组合起来。)

好在render props就提供了一个简单的复用的思路:Cat还是依赖Mouse里state的变化,state还是要传给Cat,但是经过render props一整,二者如胶似漆的状态就变得更加分离,Mouse拥有了渣男属性。对于Mouse组件来说,之前

“我心中只有你,我的state的改变是为你而存在”

的忠犬形象颠覆了,但现在

“我也可以和更多类型的组件一起为开发者大人干活了,小Cat你只是我的备胎之一哦~~”

但悲剧的事,对于Cat组件来说,还是那个傻瓜组件,一行代码都不用改,仍然纯洁得一塌糊涂!!

把Mouse和Cat写在同一个层级,将Cat作为render props传给Mouse组件,如下:

// App.js
function App() {
  return (
    <div className="App">
    {/* 这里的函数prop名字叫啥都行!不是说非得叫render */}
     <Mouse render={(props)=><Cat {...props}/>}/>
    </div>
  );
}
// Mouse.js
handleMouseMove(e){
        const {clientX,clientY}=e
        this.setState({
            x:clientX,
            y:clientY
        })
}

// 省略了很多代码

<div className="Mouse" onMouseMove={this.handleMouseMove}>
    <p>position is ({x},{y})</p>
    {this.props.render({x,y})}
</div>

render props是一个用于告知组件用于渲染什么内容的函数prop,他把组件可以动态渲染的地方暴露给外部,你不用再关注组件的内部实现,只要把数据通过函数传出去就好。

render props有什么好处?坏处?具体应用

相关阅读:Comparison: HOCs vs Render Props vs Hooks
这篇文章提到(我以为michael jackson是作者瞎掰的,居然确有其人):

A Render Prop is a function prop that a component uses to know what to render.

render props让组件知道他自己里边渲染了什么??其实也就是让开发者知道包裹的这个组件里边具体包含了什么组件,传了什么props进去,而不是像之前传统写法那样对于里面的组件一无所知,增强了代码的可读性。

如果传多个renderProps,明显可读性增加了不少/

// Login.jsx
<LoginForm
  renderButton={(DefaultButton, buttonProps) => (
    <DefaultButton {...buttonProps}>{value}</DefaultButton>
  )}
  renderInput={
    ...
  }
  renderCheckBox={
    ...
  }
/>

与几个小兄弟一起为开发者大人干活,干杯!

与Hooks结合

官方文档

export default function Mouse(props){
    const [pos,setPosition]=useState({x:0,y:0})
    return (
        <div className="Mouse" onMouseMove={(e)=>setPosition({x:e.clientX,y:e.clientY})}>
                <p>position is ({pos.x},{pos.y})</p>
                {props.render({x:pos.x,y:pos.y})}
            </div>)
}

妈呀,代码一下子清爽好多!不用再写什么class ... extends React blabla的东西了。

扩展:hooks好处?坏处?注意事项

好处:代码少了!可以用functional组件代替class了。不用bind this了(一直以来的诟病)!!(官方文档提到:class写的组件不能很好的压缩,使热重载不稳定--但不知道为什么,希望可以得到解答)

注意事项:只能在函数最外层调用hook,不要在循环、条件判断或子函数中调用。

弊端:墙裂推荐阅读-> React Hooks 你真的用对了吗?

以下概括:

  1. hook依赖的数组元素过多,难以维护,比如:
const refresh = useCallback(() => {
  // ...
}, [name, searchState, address, status, personA, personB, progress, page, size]);
  1. useMemo、useCallback的滥用。比如对于:
const resolveValue=useMemo(()=>{return compute(a,b)},[a,b]) 

如果compute()是一个非常简单的计算,使用useMemo可能会带来比直接计算更大的开销。所以在进行大型计算时使用会更好。第二个是,resolveValue值是否为对象类型,如果是对象类型因为比较的是引用,每次函数调用都会产生新的引用,所以这里用useMemo就比较合适了,但如果是原始值的时候就没什么必要,上文作者建议用useMemo来保持值的一致性。

再加上HOC

如果这种组件要用的地方很多,想扩展更多的功能,比如说这个例子中处理props,或进行渲染劫持

推荐阅读-> 深入理解 React 高阶组件

export default function withMouse(Component) {
    return class extends React.Component {
      handleProps(){
       // ...do something to props 
      }
      render() {
        const newProps=this.handleProps()

        return (
          this.props.logIn
          ?
          (<Mouse render={positions => (
            <Component {...newProps} {...positions}  />
          )}/>)
          : null
        );
      }
    }
}

hoc好处坏处??

好处:处理场景适用性很广,更加体现工厂模式。

坏处:嵌套的问题比较讨厌,不好调试。对props的劫持,不小心就污染了包裹的组件。

结尾

强烈推荐阅读这篇文章!!!Comparison: HOCs vs Render Props vs Hooks。尤其是文章后半部分,作者从可读性、复用性、定制化、调试、可测性和性能几个角度来比较这三个小兄弟,最后从开发者角度上来看render props比hooks略胜一筹,把hoc远远的甩在后边。

hoc当然没有他说的那么难用,还是看场景,起码hoc可以做很多render props不能做的事情。当然hooks也无法代替他, 推荐阅读:什么是 HOC 适合做而 React Hooks 不适合的场景? - 程墨Morgan的回答 - 知乎

最后请大家关注我的订阅号获得更加及时的推送~

那屋水泡

相关文章

  • 深入理解render props

    前言 自己对render props\hoc\hook的区别和适用场景都不怎么了解 在写文章前的个人理解: ren...

  • React高阶组件--render props、高阶组件(Rea

    React - render props和高阶组件 1,render props模式 使用步骤 1,创建一个组件,...

  • Render Props

    "Render Props"是指一种在 React 组件之间使用一个值为函数的 prop 共享代码的简单技术。具有...

  • render props

    Problem 借用react官网的例子,当我们需要一个组件的时候,我们直接去实现它,我们初始的目标...

  • Render Props

    解释 1 .一种在组件之间使用一个值为函数的共享代码的简单技术 2 .dataProvider组件接受一个函数,这...

  • render props

    了解render props之前先来回顾一下之前学习过的高阶组件HOC,高阶组件是接收一个组件作为参数,返回一个新...

  • React学习笔记2

    1.render函数对于props和state必须是纯函数 render函数不能改变props和state的属性,...

  • Hoc Vs Render Props

    1、Hoc 2、Render Props

  • React 入门实例教程

    目录 html模板 ReactDOM.render() JSX 语法 组件 & props props & 纯函数...

  • react 基本语法

    目录 html模板 ReactDOM.render() JSX 语法 组件 & props props & 纯函数...

网友评论

    本文标题:深入理解render props

    本文链接:https://www.haomeiwen.com/subject/ejzuactx.html