语法 高阶组件 - Autosizer

Syntax High order components - Autosizer

据我所知,在 documentation 之后,HOC 是一个接受组件和 returns 新组件的函数。一个例子是来自 react-redux 的函数 connect:

connect(mapStateToProps, mapDispatchToProps)(MyComponent)

我正在使用 React-virtualized 中的 Autosizer 并在其 documentation 中找到下一个定义:

High-order component that automatically adjusts the width and height of a single child.

其文档中使用的语法示例是下一个:

ReactDOM.render(
  <AutoSizer>
    {({height, width}) => (
      <List
        height={height}
        rowCount={list.length}
        rowHeight={20}
        rowRenderer={rowRenderer}
        width={width}
      />
    )}
  </AutoSizer>,
  document.getElementById('example'),
);

不确定我是否在下面提出适当的问题,让我了解正在发生的事情。如果不是,我请你忘记这两个问题,换一种方式解释。

1) 为什么 Autosizer 是 HOC?我不能说它是一个接收一个组件并返回另一个组件的函数,就像 react-redux 中的 connect 一样。

2) 在匿名函数({height, width}) => {...}中,高度和宽度是被传递对象的属性。哪个对象以及它来自哪里?

另一种思考方式是,高阶组件比它们的 children 更高阶(这意味着它们更接近 DOM 节点树),并且他们通过修改渲染他们的 children 或向他们的 children 提供额外信息。

1) Why is Autosizer a HOC?

将其视为 return 其 children 的组件更有用,但具有额外的信息。在这种情况下,child 组件可以用来修改自身的宽度和高度。

但从技术上讲,在 the source 中,它会 return 围绕您传入的 children 进行一些包装 JSX。所以它 "takes" 的组件是它的 children(在本例中为 <List>),它的组件 returns 是一个 <div>,其内容随后将您的 <List> 放入其中,同时提供它不会提供的额外信息'其他人有。

所以它与 connect 并没有什么不同,它采用一个组件,然后 returns 组件注入额外的道具,否则它会拥有。

但它是否是 HOC 在这里并不那么重要。它是一个组件,需要一个 returns JSX 作为其 children 的函数。这是重要的一点。

2) In the anonymous function ({height, width}) => {...}, height and width are properties of an object being passed. Which object and where does it come from?

首先,开始和结束标记之间的任何内容都是该组件的 children。这是最常见的某种 JSX,{} 个字符之间的纯 javascript 值。这也可以是一个函数。

所以在这种情况下,Autosizer 期望它的 children 属性是一个函数。 Autosizer 然后在渲染时调用此函数并传递一个 object 和 widthheight 作为参数。

Autosizer 可能有这样的实现:

function Autosizer({children}) {
  return children({
    width: window.outerWidth,   // or some other internal logic
    height: window.outerHeight, // or some other internal logic
  })
}

这意味着 Autosizer 有一些内部逻辑来导出一些值,然后将这些值作为参数传递给作为 children 传递的函数。

此模式称为渲染道具。 React 有 documentation about it here.


Here's a simple example 一个简单的 HOC,通过渲染属性为其 children 提供 window 大小。

您可以找到 source code for that component here,但简化版应该是这样的:

class AutoSizer extends React.PureComponent {
  // Do some extra stuff here to set width and height as they should be
  render() {
    return (
      <div
        // Call children as a function with the parameters calculated in this class
        {this.props.children({ height, width })}
      </div>
    );
  }
}

所以你传递 AutoSizer 一个 child 这是一个函数。

<AutoSizer>
  {({height, width}) => {
   // your custom logic here that uses height and width sent from AutoSizer
  }}
</AutoSizer>

AutoSizer 获取该函数作为 prop,然后使用一些计算参数调用它。