React 调用组件和 Hooks

React 负责在必要时渲染组件和 Hooks,以优化用户体验。它是声明式的:您在组件的逻辑中告诉 React 要渲染什么,React 会找出最佳方式将其显示给用户。


切勿直接调用组件函数

组件应该只在 JSX 中使用。不要像普通函数一样调用它们。应该由 React 来调用它们。

React 必须决定何时调用您的组件函数 在渲染过程中。在 React 中,您可以使用 JSX 来做到这一点。

function BlogPost() {
return <Layout><Article /></Layout>; // ✅ Good: Only use components in JSX
}
function BlogPost() {
return <Layout>{Article()}</Layout>; // 🔴 Bad: Never call them directly
}

如果一个组件包含 Hooks,那么当组件在循环或条件语句中被直接调用时,很容易违反 Hooks 规则

让 React 来协调渲染还能带来许多好处

  • 组件不仅仅是函数。 React 可以通过与树中组件标识绑定的 Hooks 来增强它们的功能,例如*本地状态*。
  • 组件类型参与协调。 通过让 React 调用您的组件,您还可以告诉它更多关于树的概念结构。例如,当您从渲染 <Feed> 切换到 <Profile> 页面时,React 不会尝试重用它们。
  • React 可以增强您的用户体验。 例如,它可以让浏览器在组件调用之间执行一些工作,这样渲染大型组件树就不会阻塞主线程。
  • 更好的调试体验。 如果组件是库所知晓的一等公民,我们就可以构建丰富的开发者工具,以便在开发中进行内省。
  • 更高效的协调。 React 可以精确地决定树中的哪些组件需要重新渲染,并跳过那些不需要重新渲染的组件。这使得您的应用程序更快、更流畅。

切勿将 Hooks 作为常规值传递

Hooks 应该只在组件或 Hooks 内部调用。切勿将其作为常规值传递。

Hooks 允许您使用 React 功能来增强组件。它们应该始终作为函数调用,而不要作为常规值传递。这使得*局部推理*成为可能,也就是说,开发人员能够通过单独查看组件来理解组件的所有功能。

违反此规则将导致 React 无法自动优化您的组件。

不要动态地改变 Hook

Hooks 应该尽可能地“静态”。这意味着您不应该动态地改变它们。例如,这意味着您不应该编写高阶 Hooks

function ChatInput() {
const useDataWithLogging = withLogging(useData); // 🔴 Bad: don't write higher order Hooks
const data = useDataWithLogging();
}

Hooks 应该是不可变的,并且不能被改变。与其动态地改变 Hook,不如创建一个具有所需功能的静态版本的 Hook。

function ChatInput() {
const data = useDataWithLogging(); // ✅ Good: Create a new version of the Hook
}

function useDataWithLogging() {
// ... Create a new version of the Hook and inline the logic here
}

不要动态使用 Hooks

也不应该动态使用 Hooks:例如,不要通过将 Hook 作为值传递来在组件中进行依赖注入。

function ChatInput() {
return <Button useData={useDataWithLogging} /> // 🔴 Bad: don't pass Hooks as props
}

您应该始终将 Hook 的调用内联到该组件中,并在其中处理任何逻辑。

function ChatInput() {
return <Button />
}

function Button() {
const data = useDataWithLogging(); // ✅ Good: Use the Hook directly
}

function useDataWithLogging() {
// If there's any conditional logic to change the Hook's behavior, it should be inlined into
// the Hook
}

这样一来,<Button /> 就更容易理解和调试了。当 Hooks 以动态方式使用时,会大大增加应用程序的复杂性,并阻碍局部推理,从长远来看会降低团队的生产力。这也更容易意外违反 Hooks 不应该被有条件地调用的Hooks 规则。如果您发现自己需要模拟组件进行测试,最好模拟服务器以使用预设数据进行响应。如果可能,通常使用端到端测试来测试您的应用程序也更有效。