人人都会AI编程

3.4 表单输入绑定:v-model 双向绑定、表单修饰符

更新时间:2026-07-10

在 React 中,我们经常需要根据不同的状态展示不同的界面,这就是条件渲染。React 不提供专用的条件渲染指令(如 Vue 的 v-if),而是直接利用 JavaScript 的表达式能力在 JSX 中实现。掌握好条件渲染,是写出灵活、可读组件的基础。

3.4.1 三元运算符(condition ? A : B

三元运算符是最常用的条件渲染方式,适用于“二选一”的场景:当条件为真时显示组件 A,否则显示组件 B。

function Greeting({ isLoggedIn }) {
  return (
    <div>
      {isLoggedIn ? <UserDashboard /> : <LoginButton />}
    </div>
  );
}

三元运算符可以内联在 JSX 的任何地方,清晰表达条件与结果的关系。如果条件逻辑较复杂,建议提前计算好条件变量,避免在 JSX 中写过长表达式:

const buttonText = isLoading ? '加载中...' : '提交';

return <button disabled={isLoading}>{buttonText}</button>;

3.4.2 逻辑与运算符(condition && <Component />

当只需要在条件为真时渲染某内容,为假时不渲染任何内容时,可以使用 && 运算符。它利用了 JavaScript 的短路特性:如果左侧表达式为真,则返回右侧的 JSX;如果为假,则返回左侧的值(React 不会渲染 falsenullundefined)。

function Notification({ hasNewMessage }) {
  return (
    <div>
      <h1>消息列表</h1>
      {hasNewMessage && <span className="badge">新消息</span>}
    </div>
  );
}

这种方式简洁直观,但需要警惕左侧值为数字 0 或 NaN 时的情况。React 会渲染数字 0,可能导致界面上出现意外的“0”。例如:

{items.length && <p>共有 {items.length} 条记录</p>}

items.length 为 0 时,条件判断为假,但 0 本身会被 React 渲染。为了避免这个问题,应该显式转换为布尔值:

{items.length > 0 && <p>共有 {items.length} 条记录</p>}

3.4.3 条件返回(提前返回)

如果组件的逻辑分支较多,或者“不满足条件时整个组件不渲染”,可以在函数组件中使用 if 语句进行提前返回。这可以让代码结构更清晰,避免深层的 JSX 嵌套。

function UserProfile({ user, isLoading, error }) {
  if (isLoading) {
    return <Spinner />;
  }

  if (error) {
    return <ErrorMessage message={error} />;
  }

  if (!user) {
    return null; // 什么都不渲染
  }

  return (
    <div className="profile">
      <h2>{user.name}</h2>
      <p>{user.email}</p>
    </div>
  );
}

上面的例子中,每种状态都是一条独立的路径,阅读时一目了然。对于复杂组件来说,这种“守卫式”提前返回是值得推荐的做法。

3.4.4 更复杂的分支:使用变量或函数

当分支超过两条时,不要强行在 JSX 中嵌套三元运算,这会严重影响可读性。更好的做法是使用变量或辅助函数来缓存 JSX 片段。

使用变量:

function StatusCard({ status }) {
  let content;
  if (status === 'loading') {
    content = <Spinner />;
  } else if (status === 'error') {
    content = <ErrorMessage />;
  } else if (status === 'empty') {
    content = <EmptyState />;
  } else {
    content = <DataView />;
  }

  return <div className="card">{content}</div>;
}

使用函数(或组件内辅助方法):

function StatusCard({ status }) {
  const renderContent = () => {
    switch (status) {
      case 'loading': return <Spinner />;
      case 'error':   return <ErrorMessage />;
      case 'empty':   return <EmptyState />;
      default:        return <DataView />;
    }
  };

  return <div className="card">{renderContent()}</div>;
}

这两种方式都把条件逻辑从 JSX 中抽离至 JavaScript 逻辑区域,保持了 JSX 的简洁性。

3.4.5 注意事项与常见陷阱

  1. 避免在 JSX 中使用复杂的逻辑

JSX 应该专注于“描述界面”,而不是承载大量判断。如果条件嵌套超过一层,请用变量或函数重构。

  1. 注意 falsenullundefined0 的渲染行为

React 不会渲染 truefalsenullundefined,但会渲染 0NaN。使用 && 运算符时,确保左侧始终是布尔值或使用显式比较。

  1. 不要用 && 替换三元运算符的 else 分支

如果需要“不为 A 则显示 B”,请使用三元运算符,而不是两个 && 搭配取反,这样更清晰。

  1. 条件返回时注意 Hooks 规则

绝不能因为条件判断而跳过 Hooks 的调用。Hooks 必须在组件顶层、无条件地按顺序调用。例如,不能在 if 语句内部调用 useStateuseEffect

  1. 考虑使用枚举或映射对象

当条件分支基于字符串常量时,可以使用对象映射代替 switch

   const componentMap = {
     loading: <Spinner />,
     error: <ErrorMessage />,
     empty: <EmptyState />,
     success: <DataView />,
   };

   return <div className="card">{componentMap[status]}</div>;
   

条件渲染虽然基础,但用好它能让组件灵活适应多种状态,同时保持代码的可读性和可维护性。选择最适合当前场景的方式,始终以“代码清晰”为第一原则。