[英]React Functional component: calling as function vs. as component
假设我有一个功能组件:
const Foo = (props) => ( <div>{props.name}</div> );
直接作为函数调用有什么区别:
const fooParent = () => (
<div> {Foo({ name: "foo" })} </div>
)
与将其作为组件调用:
const fooParent = () => (
<div> <Foo name="foo"/> </div>
)
我最感兴趣的是性能影响,React 如何在内部以不同的方式对待它们,也许在 React Fiber 中事情可能会有所不同,我听说功能组件获得了性能提升。
将其作为函数调用要快得多,事实上几个月前就有人讨论过这个问题。 在这一点上,函数式反应组件不能是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
所以我实际上遇到了一个用例,其中将渲染作为组件而不是函数调用是有益的。 使用 React 16,您可以获得错误边界功能。 这允许您在组件内引发错误时呈现回退错误 UI。 事实证明,如果在函数调用变体中抛出异常,则不会触发componentDidCatch
。 它需要在子组件中抛出。
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = {
error: false
};
}
componentDidCatch() {
this.setState({ error: true});
}
render() {
return this.state.error
? "Error :("
: this.props.children;
}
}
const renderContent = () => {
throw new Error();
}
const Content = () => {
throw new Error();
}
// This will throw exception and not trigger error state
const Foo = () => (
<ErrorBoundary>
<div>{renderContent()}</div>
</ErrorBoundary>
);
// This will trigger the error state
const Bar = () => (
<ErrorBoundary>
<div><Content /></div>
</ErrorBoundary>
);
当然,您可以将错误边界设置得更高,但只需指出一个特定用例,您可以选择其中之一。
此外,出于命名目的,将其渲染为组件也很不错。 它将在 React 开发工具中显示为命名,您也可以在进行酶测试时使用该名称作为选择器。
如果直接调用函数式组件,实际上是在调用自定义钩子。
例子:
function A() {
const [state] = useState([])
return (
<div>{state}</div>
)
}
A()
<A />
如果你调用A()
, state
挂载在父光纤中,但是如果你使用<A />
,React 将调用createElement
来创建一个新的光纤来挂载state
。
实际上,当您将其作为组件调用时,会使用React.createElement()
创建一个新元素。 另一方面,函数被直接调用。 所以,这就解释了为什么直接调用你的函数会更快。
但请记住,在某些情况下,直接调用函数可能会导致类似@dmwong2268 在这里介绍的问题,或者像这样的问题
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.