如果允许以下三个选项中的任何一个,则找不到任何 * 最近的官方 * 信息?
constructor(props) {
this.state = {
item: <SomeItem />,
item1: () => <SomeItem />,
item2: SomeItem,
};
}
我找到了this答案,但它引用了Web归档中的一个 * 旧链接 *,内容如下:
哪些内容不应进入状态?...React组件:在render()中基于底层属性和状态构建它们。
但是那个链接没有说为什么这是个坏主意,如果它会引入bug,等等。
4条答案
按热度按时间u59ebvdq1#
这是一个很好的问题。
不建议将组件置于状态的原因是,它从根本上违背了React模型,即组件提供了一个呈现方法(这是一个纯函数),React引擎使用该方法自动更新DOM以反映组件的属性和状态值。
渲染器的输出,即React元素,应该由React引擎直接使用。契约是您的应用及其所有组件以纯粹的方式生成一组元素,供React引擎管理。
通过在
render
中引入副作用,或者将元素置于状态中,你实际上是在破坏“纯”契约,它 * 可能 * 会给予不可预测的结果,这可能会也可能不会被认为是你的应用程序中的bug。bug的细节甚至可能随着React的不同版本、不同的引擎实现而变化。关键是你正在破坏React契约。因此,虽然它可能在某些情况下工作,但在其他情况下也可能不工作,甚至在React本身发生变化的相同情况下也不工作。React内置了基于prop值缓存渲染的方法,如
React.memo
,引擎提供并理解这些值,并且是契约的一部分。如果你出于性能原因想缓存渲染输出,这是一种方法。事实上,这正是React API提供此类函数而不是让您自己执行的原因。
dgtucam12#
说到底,React组件示例只是对象,而且你可以将对象存储在状态中,所以如果你避免了陷阱,就不会引起任何麻烦。其中一个陷阱是,如果你创建处理程序来放置它们的 prop ,这些处理程序将关闭创建它们的上下文,这可能会导致一些意想不到的结果。下面是一个例子:
这是典型的陈旧闭包,偶然使用函数组件和钩子(就像我在那里做的那样)而不是类组件可能更容易做到,但使用类组件也绝对是可以做到的。
但是如果您没有这样做(或者没有为您存储的组件创建函数,或者创建的函数不使用它们关闭的任何可能更改的内容),应该也没问题。
但是看看
React.memo
,这可能是一个更好的答案,取决于您希望将组件示例置于状态中的原因是什么。2j4z5cfb3#
如果我没理解错的话,你可以做这样的事
e7arh2l64#
你可以这么做,但是有点奇怪,React元素和其他元素一样是一个对象,在这个例子中,它是一个方法调用的结果:
这很奇怪,因为它是不必要的(而且有点混乱),你可以在需要的时候生成元素(包括任何状态或属性更新)。
还有一个风险是,你可能会打破React的核心保证之一:元素是不可变的。2这样存储元素会给你一个改变它的机会,从而混淆React。
如果您需要同一个元素的多个副本,那么这样保存它可能会稍微提高性能,特别是在生成它的开销很大的情况下。