这是“反应钩子的评论”的后续,它超出了预期,引发了大量的讨论,我很喜欢读这些讨论。如果你还没有读过,请在破坏测验之前绕道而行!我不是一个重复谈论一个主题的人,但在看到所有的测验结果出来后,我认为在讨论中分享这些结果以及一些关于共同主题的想法是有价值的。
在写这篇文章的时候,有2600多人回答,这是我所做过的最大的不科学测验的样本大小!即使忽略了最后一个主要是为了搞笑的问题,结果仍然非常有趣。尽管有四分之三的问题获得了正确的普选,但中位数是1分(满分4分)。对我来说,这表明人们熟悉一些钩子,但还没有用过测验中包括的所有钩子。
第一个也是最简单的问题有最高的正确率,这并不令人惊讶。然而,超过40%的人感到惊讶的是,在呈现两个组件之后,子组件的useEffect在父组件之前触发。
当我第一次运行它时,这让我很惊讶,但当您花一分钟时间考虑它时,它就有意义了。这两个useLayoutEffect都在useEffect之前运行,并且它们从组件树的底部向上运行。希望你永远不会遇到这种特殊顺序很重要的情况,因为只有30%的人第一眼就能预测到顺序。
这个问题有一个故意的缺陷,就是创建一个新的对象,不断地重现,并将它作为道具传递给孩子,这会导致备忘录运行你们三分之一的人捕捉到的每一个重现。将这些结果与围绕类似错误的问题进行比较会很有趣,该问题是在渲染器内创建函数并将其传递给子对象,每次父对象执行此操作时都会导致子对象重新呈现:
函数父(属性){函数doSomething(){//…。道具…。}return<;Child on Something={DoSomething}/>;}。
这是通过useCallback钩子修复的,测验问题是通过useRef更新对象或重构子对象的道具以不将对象作为道具修复的。这两种情况都可以来自重构类组件,在这种情况下,您的类方法或属性不会在每次呈现时都重新创建。在转换时,您必须牢记这一点,并采取模糊处理惩罚,用钩子将它们包裹起来。
这与需要重新呈现子组件但不需要重新呈现的错误类型相反。当需要useRef来维护对重新呈现的稳定引用,但随后添加了需要该值的子组件时,就会发生这种错误。如果整个引用作为道具传递,而不是当前值,子组件将不会被重新呈现,因为引用没有更改。与世隔绝,这应该不会太难发现,但当有许多道具被从不同的地方传递到一个组件时,可能会很棘手。
有一些关于钩子是多么容易学的评论。虽然我同意阅读文档并了解钩子的工作原理不会花费太长时间,但充分理解它们的后果,以及您将遇到的错误,将是一个持续的过程。测验结果显示,即使你做对了每件事,你也很可能会和没有做对的人一起工作。
增加更多的知识只会提高进入的门槛。每个开发者都应该努力消除尽可能多的进入壁垒,因为这样做最符合我们的利益。
编程语言非常强大,因为它们为您提供了可以用多种不同方式组合在一起的构建块。如果您有块循环和函数,所有可能的组合都是有效的,包括嵌套。循环中的循环、函数中的循环、循环中的函数等。挂钩没有此属性。您不能在钩子内使用钩子(不包括仅是本机钩子的包装函数的自定义钩子)。你不能在循环中使用钩子。因此,当您从使用useRef处理一件事情到需要使用useRef处理多件事情时,您不能像处理任何其他语言构建块那样,将其简单地放在循环或数组中。你必须重新设计它才能和钩子一起工作。
当你不可避免地进入调试阶段时,你应该从你期望发生的事情的心理模型开始,包括所有关于你在整个过程中将处于什么状态的假设。每当你一步一步或记录下来,当你的一个假设被打破时,你就知道你已经找到了这个错误的一部分。现在你只需要弄清楚为什么你的假设是错误的。
在钩子执行顺序和弄清楚组件重新呈现的原因之间,可能很难创建应该发生什么的心理模型。
不管你喜欢不喜欢钩子,我希望你通过这些帖子学到了一些东西,即使它不像我喜欢的那样普遍:)。
回家更多博客帖子