呈现 JSX 的函数与在另一个组件中声明组件的函数有啥区别?
Posted
技术标签:
【中文标题】呈现 JSX 的函数与在另一个组件中声明组件的函数有啥区别?【英文标题】:What's the difference between functions that render JSX vs. declaring components inside another component?呈现 JSX 的函数与在另一个组件中声明组件的函数有什么区别? 【发布时间】:2021-07-30 22:38:54 【问题描述】:这是一种反模式吗?
export function Todo()
...
const renderItem = (item) => (
item.done
? <strike>item.text</strike>
: <span>item.text</span>
);
return (
<ul>
items.map((item) => <li>renderItems(item)</li>)
</ul>
);
与在 Todo 中制作 Item 组件相比,这样渲染项目有什么区别,例如:
export function Todo()
...
const Item = (props) => (
props.item.done
? <strike>item.text</strike>
: <span>item.text</span>
);
return (
<ul>
items.map((item) => <li><Item item=item /></li>)
</ul>
);
编辑:
如何在本地创建组件/渲染函数,调用一次?
export function SomeForm(props)
const renderButton = (isComplete) => (
isComplete
? <button>Submit</button>
: <button disabled>Please complete</button>
);
return (
<form>
<input />
renderButton(props.isDone)
</form>
);
【问题讨论】:
Losing state between renders if component is defined in another component 这能回答你的问题吗? Is it an anti-pattern to define a function component inside the render() function? 【参考方案1】:事先让我们将示例修复为有效代码:
// #1
export function Todo(items)
const renderItem = (item) =>
item.done ? <strike>item.text</strike> : <span>item.text</span>;
return (
<ul>
items.map((item) => (
<li key=item.id>renderItems(item)</li>
))
</ul>
);
// #2
export function Todo(items)
const Item = (props) =>
props.item.done ? <strike>item.text</strike> : <span>item.text</span>;
return (
<ul>
items.map((item) => (
<li key=item.id>
<Item item=item />
</li>
))
</ul>
);
回到问题,是的这些都是反模式。
为什么它是反模式?
在这两个示例中,即使没有任何视觉变化,您也会重新渲染项目。
原因是因为在每次渲染时,您都重新创建了函数 (renderItem
) 和函数组件 (Item
)。
你想要什么
相反,您想让 React 执行 Reconciliation 进程,因为您需要尽可能多地渲染静态树。
最简单的解决方案是将函数/函数组件移动到外部范围或将逻辑内联到树本身。
const renderItem = (item) => (...)
const Item = (props) => (...)
export function Todo( items )
return (
<ul>
items.map((item) => (
<li key=item.id>
(item.done ? <strike>item.text</strike>:<span>item.text</span>)
</li>
))
</ul>
);
这样渲染项目有什么区别
renderItem
只是一个返回 JSX 的函数,Item
是一个 React 组件,因此它的状态被注册到 React 树(“只是一个函数”不能保持它自己的状态)。
【讨论】:
感谢您阐明“只是一个函数”和一个反应组件之间的区别!我知道这在渲染各种列表时效率特别低,但是如果我只渲染一次会怎样。那么创建“渲染”功能或本地组件仍然是反模式吗?我在编辑中添加了(一个相当做作的)示例。 您的编辑是相同的示例,仍然是反模式以上是关于呈现 JSX 的函数与在另一个组件中声明组件的函数有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章