React组件设计模式-Render-props

更新日期: 2019-09-06阅读: 2.2k标签: props

写业务时,我们经常需要抽象一些使用频率较高的逻辑,但是除了高阶组件可以抽象逻辑,RenderProps也是一种比较好的方法。

RenderProps,顾名思义就是将组件的props渲染出来。实际上是让组件的props接收函数,由函数来渲染内容。将通用的逻辑抽象在该组件的内部,然后依据业务逻辑来调用函数(props内渲染内容的函数),从而达到重用逻辑的目的。


简单实现

我们先看一个最简单的RenderProps模式的实现:

const RenderProps = props => <>
    {props.children(props)}
</>

在这里,RenderProps组件的子组件是一个函数props.children(props),而props.children返回的是UI元素。

使用时的代码如下:

<RenderProps>
    {() => <>Hello RenderProps</>}
</RenderProps>

以上未作任何的业务逻辑处理,有什么用处呢?我们可以想到,可以在 RenderProps 组件中去用代码操控返回的结果。
以最常见的用户登录逻辑为例,希望在登陆之后才可以看到内容,否则展示请登录:

const Auth = props => {
    const userName = getUserName()
    if (userName) {
        const allProps = {userName, ...props}
        return <>
            {props.children(allProps)}
        </>
    } else {
        return <>请登录</>
    }
}


<Auth>
    {({userName}) => <>Hello!{userName}</>}
</Auth>

props.children(allProps) 就相当于Auth组件嵌套的({userName}) => <>Hello!{userName}</>

上边的例子中,用户若已经登陆,getUserName返回用户名,否则返回空。这样我们就可以判断返回哪些内容了。
当然,上边通过renderProps传入了userName,这属于Auth组件的增强功能。


函数名不仅可以是children

平时一般使用的时候,props.children都是具体的组件实例,但上边的实现是基于以函数为子组件(children(props)),被调用返回UI。
同样,可以调用props中的任何函数。还是以上边的逻辑为例:

const Auth = props => {
  const userName = "Mike"
  if (userName) {
    const allProps = { userName, ...props }
    return <>{props.login(allProps)}</>
  } else {
    return <>
      {props.noLogin(props)}
    </>
  }
}

使用方法如下:

<Auth
    login={({userName}) => <h1>Hello {userName}</h1>}
    noLogin={() => <h1>please login</h1>}
  />

这里,Auth组件的props接收两个函数:login(表示已经登录)noLogin(表未登录)
Auth组件内部,通过判断是否登陆来决定显示哪个组件。


总结

render-props作为一种抽象通用逻辑的方法,其本身也会遇到像高阶组件那样层层嵌套的问题。

<GrandFather>
  {Props => {
    <Father>
      {props => {
        <Son {...props} />;
      }}
    </Father>;
  }}
</GrandFather>

但和高阶组件不同的是,由于渲染的是函数(高阶组件渲染的是组件),就为利用compose提供了机会。例如react-powerplugin。

import { compose } from "react-powerplug"

const ComposeComponent = compose(
  <GrandFather />,
  <Father />
)
<ComposeComponent>
  {props => {
    <Son {...props} />;
  }}
<ComposeComponent/>

还有Epitath也提供了一种新模式来解决这个问题。这部分展开来说的话是另一个话题了,我也在摸索中。


链接: https://fly63.com/article/detial/5685

TypeScript中的React Render Props

和之前的文章一样,本文也要求你对render props有一些知识背景,如果没有官方文档可能会对你有很大的帮助。本文将会使用函数作为children的render props模式以及结合React的context API来作为例子。

Node.js之react.js组件-Props应用

render props是指一种在 React 组件之间使用一个值为函数的 prop 共享代码(个人理解:将组件进行函数化,通过调用组件名实现,组件的利用,以元素的形式调用,并渲染画面),具有 render prop 的组件接受一个函数

props、属性、事件传递

之前看了一篇关于Vue开发技巧的文章,其中提到了在写高级组件时,通过v-bind=$props将props一次性向下传递。这种向下传递的方式我之前没有用过,便看了下官网的介绍,并补充了一些相关API用法,在这里记录一下,方便自己以后查看

props,挂载函数和快照测试

我们测试了通过一些 props 的结果。但是实际上,我们可以直接测试 props。让我们回到上次的 ToDoList组件,不过这次要用一个新的 Task 组件。我们将要测试 ToDoList 组件是否渲染 Task 组件,并将任务名称传递给他们。

vue props传值常见问题

传入的值想作为局部变量来使用,直接使用会 报错。错误是说的避免直接修改父组件传入的值,因为会改变父组件的值,解决方案:可以在data中重新定义一个变量,改变指向,但是也只是针对简单数据类型

Vue 中的 Props 与 Data 细微差别,你知道吗?

Vue提供了两种不同的存储变量:props和data。这些方法一开始可能会让人感到困惑,因为它们做的事情很相似,而且也不清楚什何时使用props,何时使用data。那么props和data有什么区别呢?

React组件的state和props

React 的数据是自顶向下单向流动的,即从父组件到子组件中,组件的数据存储在 props 和 state 中。实际上在任何应用中,数据都是必不可少的,我们需要直接的改变页面上一块的区域来使得视图的刷新

验证 Vue Props 类型,这几种方式你可能还没试用过!

vue 要求任何传递给组件的数据,都要声明为 props。此外,它还提供了一个强大的内置机制来验证这些数据。这就像组件和消费者之间的契约一样,确保组件按预期使用。

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!