说我有一个功能组件:
const Foo = (props) => ( <div>{props.name}</div> );
直接将其作为函数调用有什么区别:
const fooParent = () => (
<div> {Foo({ name: "foo" })} </div>
)
与将其称为组件:
const fooParent = () => (
<div> <Foo name="foo"/> </div>
)
我最感兴趣的是性能影响,React如何在内部对待它们,以及React Fiber的情况可能会有所不同,我听到功能组件的性能提升。
答案 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