React功能组件与返回React元素的普通JS函数

时间:2017-05-31 15:47:03

标签: javascript reactjs react-jsx

假设我定义了一个简单的React功能组件:

const Greeter1 = ({name}) => <h1>Hello {name}</h1>;

我还可以定义一个等效的普通旧JS函数,它返回一个React元素,如下所示:

const Greeter2 = name => <h1>Hello {name}</h1>;

&#34; React&#34; version当然也只是一个普通的JS函数,它接受一个JS对象而不是一个字符串。我们可以在普通JS中使用这些函数中的任何一个来获取给定名称的greeter元素,只需稍微调用不同的调用者语法:

const greeterElement1 = Greeter1({ name: "Bob" });
const greeterElement2 = Greeter2("Bob");

在React表达式中,我们可以通过几种不同的方式调用这些函数:

const someReact1 = <div>{ Greeter2("Bob") }</div>;
const someReact2 = <div>{ Greeter1({ name: "Bob" }) }</div>;
const someReact3 = <div><Greeter1 name="Bob" /></div>;

我的问题:除了语法美学之外,这些调用样式之间是否存在任何有效差异?我认为someReact1someReact2几乎完全相同,但我对someReact3不确定。使用React组件语法是否会改变React处理事物的方式?它会以任何方式影响行为或表现吗?或者仅仅是语法糖?

当在虚拟DOM树上进行差异时,如果在渲染之间其属性没有改变,React是否会在功能组件内进行比较?如果是这样,我是否正确地假设在someReact1中直接调用函数时会丢失优化?

我想知道b / c在某些情况下我实际上更喜欢someReact1的风格,因为它允许我使用函数式编程技术,比如更容易进行curry,另外有时它很不错。调用时指定参数名称。但是这样做我会付出某种代价吗?我最好坚持传统的语法吗?

2 个答案:

答案 0 :(得分:1)

自React 16以来,组件函数比类组件多(a bit?) faster。不确定先前版本是否为真。

将组件函数作为函数进行调用比通过JSX / import pandas as pd from tabula import read_pdf df=read_pdf(Attendance_Test.pdf",pages="1") new_header = df.iloc[0] df = df[1:] df.columns = new_header df.rename(columns={'Registers Present Late Absent':'RPLA'}, inplace=True) df.rename(columns={'Withdra Unmarked Attend%':'WUA'}, inplace=True) df_RPLA=df['RPLA'].str.split(' ', expand=True) df_RPLA.columns = ['Registers','Present','Late','Absent'] df_WUA=df['WUA'].str.split(' ', expand=True) df_WUA.columns = ['Withdrawn','Unmarked','Attendance%'] result = pd.concat([pd.DataFrame(df['Student']), df_RPLA,df_WUA ], axis=1) result 进行调用要much faster。 但是,在大多数情况下,这不会影响我们编写代码的方式,因为JSX可读性强。为了填补这一空白,我们应该使用@babel/plugin-transform-react-inline-elements

但是,我了解您将其称为函数的热情。为了构成,我也觉得它很有用。对于普通函数更是如此。
但是,再次functional components are going to have a state。如果发生这种情况,我们可能会后悔我们的热情:)

普通功能seem to be faster比组件功能简单。但是,我还没有挖掘这个话题。例如,我不确定React.createElement是否可以正常工作。或者,它在性能和可能的优化方面的利弊。


IMO,无论有何区别,无论如何,优化仍在我们身上 –是react-hot-reload,备忘录或密钥。可能不需要任何优化的组件应该廉价重新渲染,反之亦然(显然,如果是纯计算,而不是DOM操作)。

随时发表评论或纠正,我将更新我的帖子。

答案 1 :(得分:0)

我找到了一个解释,显然有人在官方React仓库的Github问题中问了类似的问题。这是指向问题https://github.com/facebook/react/issues/16796的链接以及该线程的摘录,一个由贡献者提供的答案:

我想了解的是:实际上有必要打电话吗 再次React.createElement,因为它已经在的返回值中 组件?那和之间有什么有效的区别吗 像这样直接调用函数组件?

正如@hamlim所提到的,有效的区别在于,如果组件比返回另一个React元素的纯函数更复杂,则简单地将组件作为函数调用是行不通的。 React需要从React.createElement返回的元素来处理这些功能。

HelloMessage示例中,从技术上讲,您可以将其作为一个函数来调用,这等效于:

ReactDOM.render(
  <div>Hello Taylor</div>,
  document.getElementById("hello-example")
);

这只是内嵌HelloMessage的结果,它将在浏览器中呈现相同的UI。通过调用HelloMessage作为函数可以有效地完成您的工作。在内部,这与React有所不同,因为没有安装任何组件,但实际上在这个简单的示例中,行为是相同的。

对于ParentComponent示例,适用相同的约束。如果ChildComponent组件只是没有状态或效果的简单组件,则可以 称为函数,这与将它们的内容内联到ParentComponent中的结果相同。在相同的情况下,这可能是您想要的,但通常不是。如果有人将状态或效果添加到ChildComponent之一中,或将其包装在React.memoReact.lazy中,则会破坏状态或效果。因此请谨慎使用此模式。