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

f45qwnt8  于 2023-04-04  发布在  Java
关注(0)|答案(2)|浏览(118)

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

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>
  );
}

它看起来很好,我看不到任何直接的负面影响,但是否有一些根本的原因,为什么我们不应该定义CustomComponent功能组件从另一个组件?
CodeSandbox示例:https://codesandbox.io/s/dreamy-mestorf-6lvtd?file=/src/App.tsx:0-342

7fyelxc5

7fyelxc51#

这不是一个好主意。每次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>
  );
}

有时,你可能在一个组件中做一些重复的事情,并希望通过一个helper函数来简化代码。这是可以的,但你需要将它作为一个函数调用,而不是将它作为一个组件呈现。

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

使用这种方法,react将比较<h1><h1>,因此不需要重新挂载它。

p5cysglq

p5cysglq2#

这不仅是个坏主意,更是个可怕的主意.
这是一个可怕的想法,因为react组件有一个生命周期。它们被挂载,它们可以在自己或树中较低的位置(它们渲染的东西)维护状态。但如果组件定义在父组件的每次渲染时都发生更改,这就不会发生。你最终会看到奇怪的bug,比如状态似乎在奇怪的时候被重置。
之所以要在另一个组件中声明一个组件,唯一的原因是关闭一个prop(也许也是一些state),你想在一个子组件中捕获它-这里的技巧-将它作为一个 prop 传递给一个新组件,然后你可以在外部声明新组件。
转这个:

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>
  );
}

变成这样:

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>
  );
}

相关问题