Javascript 在React中,我可以在另一个功能组件的主体中定义一个功能组件吗?

Javascript 在React中,我可以在另一个功能组件的主体中定义一个功能组件吗?,javascript,reactjs,jsx,react-functional-component,Javascript,Reactjs,Jsx,React Functional Component,我已经开始看到我的团队中的一些人在写下面的代码,这让我怀疑我们是否以正确的方式做事,因为我以前从未见过这样的代码 import * as React from "react"; import "./styles.css"; function UsualExample() { return <h1>This is the standard example…</h1> } export default function App() { const CustomCo

我已经开始看到我的团队中的一些人在写下面的代码,这让我怀疑我们是否以正确的方式做事,因为我以前从未见过这样的代码

import * as React from "react";
import "./styles.css";

function UsualExample() {
  return <h1>This is the standard example…</h1>
}

export default function App() {
  const CustomComponent = (): JSX.Element => <h1>But can I do this?</h1>
  return (
    <div className="App">
      <UsualExample />
      <CustomComponent />
    </div>
  );
}

import*as React from“React”;
导入“/styles.css”;
函数UsualExample(){
return这是标准示例…
}
导出默认函数App(){
const CustomComponent=():JSX.Element=>但是我可以这样做吗?
返回(
);
}
它看起来很好,我看不到任何直接的负面影响,但有什么根本原因不应该从另一个组件中定义
CustomComponent
功能组件

代码沙盒示例:
这不是个好主意。每次
App
重新发布时,它都会为CustomComponent创建一个全新的定义。它具有相同的功能,但由于它是一个不同的引用,react将需要卸载旧引用并重新装载新引用。因此,您将强制react对每个渲染执行额外的工作,并且还将重置CustomComponent中的任何状态

相反,组件应该自己声明,而不是在渲染内部声明,以便只创建一次,然后重用。如有必要,您可以让组件接受道具来自定义其行为:

const CustomComponent = (): JSX.Element => <h1>But can I do this?</h1>

export default function App() {
  return (
    <div className="App">
      <UsualExample />
      <CustomComponent />
    </div>
  );
}
constcustomcomponent=():JSX.Element=>但我可以这样做吗?
导出默认函数App(){
返回(
);
}
有时,您可能在单个组件中重复执行某些操作,并希望通过使用helper函数来简化代码。这没关系,但是您需要将其作为函数调用,而不是作为组件呈现

export default function App() {
  const customCode = (): JSX.Element => <h1>But can I do this?</h1>
  return (
    <div className="App">
      {customCode()}
      <UsualExample />
      {customCode()}
    </div>
  );
}
导出默认函数App(){
const customCode=():JSX.Element=>但我可以这样做吗?
返回(
{customCode()}
{customCode()}
);
}

使用这种方法,react将把
进行比较,因此它不需要重新装载它。

这不仅是个坏主意,而且是个可怕的主意。你还没有发现构图(没关系,需要一段时间,你会找到的)

您想要在另一个组件中声明组件的唯一原因是关闭您想要在子组件中捕获的
道具
(可能还有一些
状态
),这里有一个诀窍-将其作为道具传递给新组件,然后您可以在外部声明新组件

把这个翻过来:

function UsualExample() {
  return <h1>This is the standard example…</h1>
}

export default function App({someProp}) {
  // the only reason you're declaring it in here is because this component needs "something" that's available in <App/> - in this case, it's someProp
  const CustomComponent = (): JSX.Element => <h1>I'm rendering {someProp}</h1>
  return (
    <div className="App">
      <UsualExample />
      <CustomComponent />
    </div>
  );
}
函数UsualExample(){
return这是标准示例…
}
导出默认函数App({someProp}){
//在这里声明它的唯一原因是因为该组件需要在中可用的“某物”——在本例中,它是someProp
const CustomComponent=():JSX.Element=>我正在渲染{someProp}
返回(
);
}
为此:

function UsualExample() {
  return <h1>This is the standard example…</h1>
}

const CustomComponent = ({someProp}) => <h1>I'm rendering {someProp}></h1>

export default function App({someProp}) {
  return (
    <div className="App">
      <UsualExample />
      { /* but all you have to do is pass it as a prop and now you can declare your custom component outside */ }
      <CustomComponent someProp={someProp} />
    </div>
  );
}
函数UsualExample(){
return这是标准示例…
}
const CustomComponent=({someProp})=>我正在渲染{someProp}>
导出默认函数App({someProp}){
返回(
{/*但您所要做的就是将其作为道具传递,现在您可以在*/}之外声明自定义组件
);
}

是的,你可以!永远不要这样做,这是不合逻辑的,毫无意义。感谢您的回答,这是有意义的,并涵盖了有关渲染性能的坏主意的细节。我们经常使用你上面提到的帮助函数方法,所以我们会坚持使用它,或者你和Adam都提到过,如果我们想要一个组件,就把它抽象成另一个函数。“帮助函数”与组件有着完全相同的问题。它们只需要关闭函数范围内可用的某个变量。只需将这些变量作为参数传递给helper函数,并从组件中提取helper函数。在组件内部声明函数(不使用
useCallback
)是糟糕的性能、糟糕的设计、糟糕的一切。
“helper函数”与组件有着完全相同的问题
,虽然肯定有反对helper函数的论点,但它们不存在不同的元素类型,因此,它们不会导致对账者错误地认为元素已更改。@NicholasTower-在上面的示例中,将
customCode()
更改为
,然后看看会发生什么-这是一条很细的线。您所做的是创建了一个组件(它返回JSX对吗?),但称它为不同的组件(它不是),因此现在它无法从众多性能优化中获益。是的,我非常清楚
customCode()
有不同的结果。这正是我回答的重点。“这不仅是个坏主意,也是个可怕的主意。”-应该解释一下原因。“你还没有发现组成(没关系,需要一段时间,你会找到的)。”-这有点傲慢,没有必要,特别是因为OP说“我已经开始看到我的一些团队编写以下代码”,并询问观察到的模式。并不是所有的语言或框架都有嵌套函数声明的优化问题,所以这不是必然的结果。