admin管理员组文章数量:1330604
I've started seeing some of my team writing the following code which made me question if we're doing things the right way as I hadn't seen it written like this before.
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>
);
}
It seems to render fine and I can't see any immediate adverse effects but is there some fundamental reason why we shouldn't be defining CustomComponent
functional ponent from within another ponent?
CodeSandbox Example: =/src/App.tsx:0-342
I've started seeing some of my team writing the following code which made me question if we're doing things the right way as I hadn't seen it written like this before.
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>
);
}
It seems to render fine and I can't see any immediate adverse effects but is there some fundamental reason why we shouldn't be defining CustomComponent
functional ponent from within another ponent?
CodeSandbox Example: https://codesandbox.io/s/dreamy-mestorf-6lvtd?file=/src/App.tsx:0-342
Share Improve this question asked May 27, 2020 at 15:59 JustynJustyn 1,50013 silver badges28 bronze badges 1- 2 Yes you can! Don't ever do this, it's illogical and makes no sense. – Adam Jenkins Commented May 27, 2020 at 16:06
2 Answers
Reset to default 12This is not a good idea. Every time App
rerenders it will make a brand new definition for CustomComponent. It has the same functionality, but since it's a different reference, react will need to unmount the old one and remount the new one. So you will be forcing react to do extra work on every render, and you'll also be resetting any state inside CustomComponent.
Instead, ponents should be declared on their own, not inside of rendering, so that they are created just once and then reused. If necessary, you can have the ponent accept props to customize its behavior:
const CustomComponent = (): JSX.Element => <h1>But can I do this?</h1>
export default function App() {
return (
<div className="App">
<UsualExample />
<CustomComponent />
</div>
);
}
On occasion, you may be doing something repetitive inside a single ponent and want to simplify the code by having a helper function. That's ok, but then you'll need to call it as a function, not render it as a ponent.
export default function App() {
const customCode = (): JSX.Element => <h1>But can I do this?</h1>
return (
<div className="App">
{customCode()}
<UsualExample />
{customCode()}
</div>
);
}
With this approach, react will be paring an <h1>
with an <h1>
, and so it does not need to remount it.
It's not only a bad idea, it's a horrible idea.
It’s a horrible idea because react ponents have a life cycle. They get mounted, and they can maintain state either in themselves or somewhere lower in their tree (the things they render). But this can’t happen if the ponent definition changes on every render of a parent. You’ll end up seeing weird bugs like state getting seemingly reset at odd times.
The only reason why you want to declare a ponent inside of another one is to close over a prop
(maybe some state
too, perhaps) that you want to capture in a child ponent - here's the trick - pass it as a prop to a new ponent and you can then declare the new ponent OUTSIDE.
Turn this:
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 ponent 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>
);
}
Into this:
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 ponent outside */ }
<CustomComponent someProp={someProp} />
</div>
);
}
本文标签:
版权声明:本文标题:javascript - In React, can I define a functional component within the body of another functional component? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1740883742a2301502.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论