React Functional组件:作为函数调用而不是组件

时间:2017-10-26 23:27:37

标签: javascript reactjs

说我有一个功能组件:

const Foo = (props) => ( <div>{props.name}</div> );

直接将其作为函数调用有什么区别:

const fooParent = () => (
    <div> {Foo({ name: "foo" })} </div>
)

与将其称为组件:

const fooParent = () => (
    <div> <Foo name="foo"/> </div>
)

我最感兴趣的是性能影响,React如何在内部对待它们,以及React Fiber的情况可能会有所不同,我听到功能组件的性能提升。

4 个答案:

答案 0 :(得分:5)

将它作为一个函数调用要快得多,实际上几个月之前就有一个关于这个问题的讨论。此时,功能反应组件不能PureComponents,因此不会对它们进行额外的优化。

基本上,如果您可以将功能组件称为消除整个反应生命周期的功能。如果你考虑一下,你甚至可能在你的渲染方法中使用这种技术。考虑一下:

... some component ... 

render() {

  const tabHeaders =<TabHeaders>{this.props.tabs.map(this.renderTabHeader)}</TabHeader>;
  const tabContents = <TabContents>{this.props.tabs.map(this.renderTabContent)}</TabContents>;

  return (<div>
    {this.props.tabsBelow?[tabContents, tabHeaders] : [tabHeaders, tabContents]}
  </div>);
} 

renderTabHeader方法返回一些反应组件,可能是功能组件,但在这种情况下只是一些组件类方法。

有关详细说明,请参阅此文章:https://medium.com/missive-app/45-faster-react-functional-components-now-3509a668e69f

另请查看正在执行该操作的babel插件:https://babeljs.io/docs/plugins/transform-react-inline-elements

答案 1 :(得分:2)

所以我实际上遇到了一个用例,它有利于渲染为组件而不是函数调用。使用React 16,您将获得错误边界功能。这允许您在组件中引发错误时呈现回退错误UI。事实证明,如果在函数调用变体中抛出异常,它将不会触发a。它需要抛出一个子组件。

timestamp with time zone

当然,您可以将错误边界设置得更高,但只需指出一个特定用例,您可以选择其中一个。

此外,最好将其作为命名目的进行渲染。它将显示在React dev工具中命名,当您进行酶测试时,您也可以使用该名称作为选择器。

答案 2 :(得分:2)

如果直接调用功能组件,则实际上是在调用自定义钩子。

示例:

function A() {
  const [state] = useState([])
  return (
    <div>{state}</div>
  )
}

A()
<A />

如果调用A(),则state将安装在父光纤中,但是如果使用<A />,React将调用createElement来创建要安装的新光纤。 state

答案 3 :(得分:1)

实际上,当您将其称为组件时,会使用React.createElement()创建一个新元素。另一方面,直接调用该函数。 因此,这说明了为什么直接调用函数更快的原因。

但是请记住,在某些情况下,直接调用函数可能会导致问题,例如@ dmwong2268此处介绍的问题或类似this one