Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/420.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 反应功能组件:作为功能调用与作为组件调用_Javascript_Reactjs - Fatal编程技术网

Javascript 反应功能组件:作为功能调用与作为组件调用

Javascript 反应功能组件:作为功能调用与作为组件调用,javascript,reactjs,Javascript,Reactjs,假设我有一个功能组件: const Foo = (props) => ( <div>{props.name}</div> ); const fooParent = () => ( <div> <Foo name="foo"/> </div> ) constfoo=(props)=>({props.name}); 直接将其作为函数调用有什么区别: const fooParent = () => (

假设我有一个功能组件:

const Foo = (props) => ( <div>{props.name}</div> );
const fooParent = () => (
    <div> <Foo name="foo"/> </div>
)
constfoo=(props)=>({props.name});
直接将其作为函数调用有什么区别:

const fooParent = () => (
    <div> {Foo({ name: "foo" })} </div>
)
const foopparent=()=>(
{Foo({name:'Foo})}
)
与将其称为组件相比:

const Foo = (props) => ( <div>{props.name}</div> );
const fooParent = () => (
    <div> <Foo name="foo"/> </div>
)
const foopparent=()=>(
)

我最感兴趣的是性能影响,React如何在内部对它们进行不同的处理,以及React Fiber中的情况可能会有什么不同,我听说功能组件的性能得到了提升。

将其称为函数要快得多,事实上,几个月前就有人谈论过这一点。在这一点上,功能性的react组件不可能实现,因此没有对它们进行额外的优化

基本上,如果您可以将功能组件作为消除整个生命周期的功能调用。如果您仔细想想,您可能正在渲染方法中使用此技术,即使是现在。考虑这一点:

... 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>);
} 
。。。某些组件。。。
render(){
const tabHeaders={this.props.tabs.map(this.renderTabHeader)};
const tabContents={this.props.tabs.map(this.renderabcontent)};
返回(
{this.props.tabsBelow?[tabContents,tabHeaders]:[tabHeaders,tabContents]}
);
} 
renderTabHeader方法返回一些react组件,可能是功能组件,但在本例中只是一些组件类方法

有关详细说明,请参阅本文:


还可以查看这个babel插件:

因此我实际上遇到了一个用例,在这个用例中,作为组件而不是函数调用进行渲染是有益的。使用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>
);
类ErrorBoundary扩展React.Component{
建造师(道具){
超级(道具);
此.state={
错误:false
};
}
componentDidCatch(){
this.setState({error:true});
}
render(){
返回this.state.error
“错误:(”
:这个。道具。儿童;
}
}
常量renderContent=()=>{
抛出新错误();
}
常量内容=()=>{
抛出新错误();
}
//这将引发异常,而不是触发错误状态
常量Foo=()=>(
{renderContent()}
);
//这将触发错误状态
常数条=()=>(
);
当然,您可能会有更高的错误边界,但只是指出一个特定的用例,您可以在其中选择一个


另外,出于命名目的呈现为组件也很好。它将在React-dev工具中显示为named,并且当您进行酶测试时,您也可以使用该名称作为选择器。

实际上,当您将其作为组件调用时,将使用
React.createElement()
创建一个新元素。另一方面,直接调用该函数。 这就解释了为什么直接调用函数会更快


但请记住,在某些情况下,直接调用函数可能会导致问题,如@dmwong2268在此处引入的问题,或者类似于

如果直接调用函数组件,则实际上是在调用自定义挂钩

例如:

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

A()
<A />
函数A(){
常量[状态]=使用状态([])
返回(
{state}
)
}
()

如果调用
A()
状态
安装在父光纤中,但如果您使用
,React将调用
createElement
创建一个新光纤,在其上安装
状态

您能总结一下为什么将其作为函数调用更快吗?另外,如果没有缺点,那么为什么这样做不是标准?看起来像most文档指出了将功能组件称为组件的方向。啊..这篇文章实际上是我提出这个问题XD的原因。这也是关于React Fiber的部分-这篇文章中有一条评论,暗示已经对功能组件进行了优化,以使其更快。我想知道impac测试结果。正确的方法是测量。但一般来说,你几乎不能比没有代码更快。你能分享一下你在回答中谈论的“谈话”吗?在react的新版本中仍然是这样吗?