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

Jus*_*tyn 3 javascript jsx reactjs 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 CustomComponent = (): JSX.Element => <h1>But can I do this?</h1>
  return (
    <div className="App">
      <UsualExample />
      <CustomComponent />
    </div>
  );
}

Run Code Online (Sandbox Code Playgroud)

它似乎渲染得很好,我看不到任何直接的不利影响,但是否有一些根本原因为什么我们不应该CustomComponent从另一个组件中定义功能组件?

CodeSandbox 示例:https ://codesandbox.io/s/dreamy-mestorf-6lvtd ? file =/ src/App.tsx:0-342

Nic*_*wer 5

这不是一个好主意。每次重新App渲染都会为 CustomComponent 做出一个全新的定义。它具有相同的功能,但由于它是不同的引用,因此 React 将需要卸载旧的并重新安装新的。因此,您将强制 react 在每次渲染上做额外的工作,并且您还将重置 CustomComponent 内的任何状态。

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

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

export default function App() {
  return (
    <div className="App">
      <UsualExample />
      <CustomComponent />
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

有时,您可能会在单个组件中做一些重复的事情,并希望通过使用辅助函数来简化代码。没关系,但是您需要将其作为函数调用,而不是将其呈现为组件。

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

使用这种方法,react 会将 an<h1>与 an进行比较<h1>,因此不需要重新安装它。


Ada*_*dam 5

这不仅是一个坏主意,而且是一个可怕的主意。

\n

这是一个可怕的想法,因为 React 组件有生命周期。它们被挂载,并且可以在自身或树中较低的位置(它们渲染的东西)维护状态。但是,如果组件定义在父级的每次渲染上发生更改,则可能会\xe2\x80\x99 发生这种情况。你\xe2\x80\x99最终会看到奇怪的错误,比如状态似乎在奇怪的时间被重置。

\n

您想要在另一个组件内部声明一个组件的唯一原因是关闭您想要在子组件中捕获的prop(也许还有一些) - 这是技巧 - 将其作为道具传递给新组件并state然后您可以在外部声明新组件。

\n

转这个:

\n
function UsualExample() {\n  return <h1>This is the standard example\xe2\x80\xa6</h1>\n}\n\nexport default function App({someProp}) {\n  // 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\n  const CustomComponent = (): JSX.Element => <h1>I'm rendering {someProp}</h1>\n  return (\n    <div className="App">\n      <UsualExample />\n      <CustomComponent />\n    </div>\n  );\n}\n
Run Code Online (Sandbox Code Playgroud)\n

进入这个:

\n
function UsualExample() {\n  return <h1>This is the standard example\xe2\x80\xa6</h1>\n}\n\nconst CustomComponent = ({someProp}) => <h1>I'm rendering {someProp}></h1>\n\nexport default function App({someProp}) {\n  return (\n    <div className="App">\n      <UsualExample />\n      { /* but all you have to do is pass it as a prop and now you can declare your custom component outside */ }\n      <CustomComponent someProp={someProp} />\n    </div>\n  );\n}\n
Run Code Online (Sandbox Code Playgroud)\n

  • “这不仅是一个坏主意,而且是一个可怕的主意。” - 应该解释原因。“你还没有发现构图(没关系,需要一段时间,你就会到达那里)。” - 这有点居高临下且不必要,特别是因为 OP 表示“我已经开始看到我的团队中的一些人编写以下代码”并且正在询问观察到的模式。并非所有语言或框架都存在嵌套函数声明的优化问题,因此这不是一个既定的结论。 (5认同)