呈现 JSX 的函数与在另一个组件中声明组件的函数有什么区别?



这是反模式吗?

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

让我们先将示例固定到一个有效的代码中:

// #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执行"协调"过程,因为它需要尽可能多地呈现一个静态树。

最简单的解决方案是将函数/函数组件移动到外部范围,或者将逻辑内联到树本身中。

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树中("只是一个函数"不能保持自己的状态(。

相关内容

最新更新