你知道吗,你可以把任何React应用写成一个单一的React组件?从技术上来说,没有任何东西可以阻止React把你的整个应用放到一个巨大的组件中。你的功能将是巨大的,会有大量的状态和副作用的钩子,但这是完全可能的。
如果你尝试这样做,你会面临一些问题:
- 性能可能会受到影响。每一个状态的改变都会导致整个应用程序的重新渲染。
- 代码共享/重用性将...不容易。至少如果你把它变成一个类组件,如果你想用
componentDidCatch来处理运行时的错误,你可能必须这么做。如果你被允许使用react-error-boundary,这样你就可以使用钩子,那么它就会容易得多。但是...我想说的是... - 状态将是一个挑战:知道哪些状态和事件处理程序与JSX的哪些部分相匹配,会让你头疼不已😬,并导致一些难以追踪的错误🐜(这就是关注点分离的一个好处)。
- 测试将是100%的集成:这不一定是件坏事,但要测试边缘案例并将事情隔离在你试图测试的部分是相当困难的,所以你将遭受过度测试的痛苦(这是E2E测试中的一个常见错误)。
- 与多个工程师一起工作在代码库上将是非常糟糕的。你能想象git diffs和合并冲突吗?
- 使用第三方组件库将是......嗯......不可能的?如果我们把所有的东西都写成一个单一的组件,那么第三方库就与这个目标相悖了即使我们允许使用第三方组件,那么像react-emotion这样的HOCs呢?不允许!(此外,无论如何你都应该使用
css道具😉)。 - 在一个更加声明性的组件API中封装指令性抽象/API也是不允许的,这意味着指令性API会在我们这个巨大的组件的生命周期钩子中到处都是,从而导致代码更难遵循。(同样,除非你使用钩子,在这种情况下,你可以把相关的钩子组合在一起,使其更容易管理,但仍然是一个有点糟糕的噩梦)。
这些都是我们编写自定义组件的原因。它使我们能够解决这些问题。
我的AMA上有一个问题:将应用程序分割成组件的最佳方法/模式。 这就是我的回答。"当你遇到上述问题之一时,就是你把你的组件分成多个小组件的时候。而不是之前。" 将一个组件分解成多个组件就是所谓的 "抽象"。抽象是很好的,但每一个抽象都是有代价的,你必须在采取这种做法之前了解这种代价和好处
所以我不介意我在组件函数中返回的JSX变得非常长。 记住,JSX只是一堆使用组件给出的声明性API的JavaScript表达式。这样的代码不会出什么差错,而且保持代码的原样要比把事情分解成一堆小的组件并开始到处进行Prop Drilling要容易得多。
结论
所以,你可以自由地将你的组件分解成更小的组件,但是在你开始遇到真正的问题之前,不要害怕一个不断增长的组件。维护它直到它需要被拆分,比维护一个不成熟的抽象要容易得多。祝您好运!