什么是渲染道具,它与高阶组件有什么不同?

Xle*_*lee 11 render reactjs

这似乎使道具还没有得到足够的牵引力,到目前为止,然而,它的广泛使用,久负盛名的反应的库,例如react-router 4,react motion等和应对网站也有这方面的专门一节,任何原因出现的模式,如何进行比较,俗称HOC(高阶分量)模式?

Xle*_*lee 10

为我的研究留下答案,非常欢迎不同的答案和讨论!

HOC借鉴了高阶函数的概念:

高阶函数(也是函数,函数形式或函子)是至少执行以下任一操作的函数:

  • 将一个或多个函数作为参数(即过程参数),
  • 返回一个函数作为结果.[争议 - 讨论]

HOC

高阶组件(HOC)是React中用于重用组件逻辑的高级技术.

源于这个要点.

这种模式是关于静态组成的.核心/可重用逻辑封装在HOC中,同时将移动部件留给组件.

使用withRouter从反应路由器为例:

withRouter会在呈现时将更新的匹配,位置和历史道具传递给包装组件.

//这会绕过shouldComponentUpdate

withRouter(连接(...)(MyComponent的))

现在你得到一个增强的MyComponent,它有{ history, match, location, ...connectProps, ...ownProps }路由器HOC传递的道具.

一种常见的方法是

compose(
  connect( ... ),
  enhance( ... ),
  withRouter( ... ),
  lifecycle( ... ),
  somethingElse( ... )
)(MyComponent);  
Run Code Online (Sandbox Code Playgroud)

最重要的是,您可以使用组合实用程序无限地组合这些HOC 以获得组件的最终增强版本,并且您的组件将获得有关从HOC返回的新组件注入的redux存储,反应路由器等的知识.

该方法的缺点是:

  1. 组件的行为是在运行时之前定义的,因此失去了react的渲染生命周期的力量,比如说你做不了类似的事情:

    compose(
      this.state.shouldConnect && connect( ... ),
      this.state.shouldEnhance && enhance( ... ),
      this.state.shouldWithRouter && withRouter( ... ),
      ...
    )(MyComponent); 
    
    Run Code Online (Sandbox Code Playgroud)

    因为state/ props在您的代码运行之前不可用.

  2. 间接和命名冲突.

使用带有ES6类的HOC会产生许多与mixin对createClass相同的问题,只是重新排列了一下.

HOC引入了很多仪式,因为它们包装组件并创建新组件而不是混合到现有组件中.


渲染道具

渲染道具是一个组件用来知道渲染内容的函数道具.

最初采用反应运动,早在Dan's Gist中首次提交redux之前几周.

这种模式是关于DYNAMIC的组成.核心/可重用逻辑保留在组件中,而移动部件作为回调道具传递.

您可以通过渲染道具创建HOC.

仍以withRouter为例:

const withRouter = Component => {
  const C = props => {
    const { wrappedComponentRef, ...remainingProps } = props;
    return (
      <Route
        render={routeComponentProps => (
          <Component
            {...remainingProps}
            {...routeComponentProps}
            ref={wrappedComponentRef}
          />
        )}
      />
    );
  };
  ...
  return hoistStatics(C, Component);
}; 
Run Code Online (Sandbox Code Playgroud)

而事实恰恰相反.

<Connect render={connectPropsMergedWithState => {
  <Enhance render={enhancePropsMergedWithState => {
    <WithRouter render={routerPropsMergedWithState => {
      <Lifecycle render={lifecyclePropsMergedWithState => {
        <SomethingElse render={somethingElsePropsMergedWithState => {
          ...
        }/>
        ...
      }/>
      ...
    }/>
    ...
  }/>
  ...
}/>
Run Code Online (Sandbox Code Playgroud)

虽然看起来不太好,但它有很多收益.

  1. 它具有更好的显式性,因为我们可以看到完全作为参数传递到渲染道具的内容.
  2. 由于1,它使我们免于潜在的道具碰撞.
  3. 它是动态的,我们可以传递任何我们喜欢的东西(包括state/ props)来渲染道具.

众所周知的缺点是性能优化很棘手,因为接收的props会延迟到运行时.并且进行任何过早优化可能不是一个好主意,但这可能是另一个主题.

如果你同意反应路由器从3到4的方向移动,渲染道具可能是你的果酱.

参考文献:

  1. https://cdb.reacttraining.com/use-a-render-prop-50de598f11ce
  2. https://reactrocket.com/post/turn-your-hocs-into-render-prop-components