Skip to content

逻辑与运算符渲染

学习目标

通过本章学习,你将全面掌握:

  • 逻辑与运算符的渲染原理
  • &&运算符的正确使用
  • 常见陷阱和完整解决方案
  • 逻辑或运算符的使用
  • 空值合并运算符(??)
  • 可选链运算符(?.)
  • 各种运算符的组合使用
  • React 19中的最佳实践

第一部分:逻辑与运算符基础

1.1 基本用法

jsx
// 语法:condition && expression
// 如果condition为true,返回expression并渲染
// 如果condition为false,返回false(React不渲染false)

function BasicLogicalAnd({ isLoggedIn, hasPermission, isActive }) {
  return (
    <div>
      <h1>主页</h1>
      
      {/* isLoggedIn为true时显示欢迎语 */}
      {isLoggedIn && <p>欢迎回来!</p>}
      
      {/* hasPermission为true时显示管理面板 */}
      {hasPermission && <AdminPanel />}
      
      {/* isActive为true时显示在线状态 */}
      {isActive && <span className="status-online">在线</span>}
    </div>
  );
}

1.2 单一条件渲染

jsx
function SingleCondition({ 
  showMessage, 
  hasNotifications, 
  isOnline,
  isPremium,
  isVerified 
}) {
  return (
    <div>
      {/* 显示消息 */}
      {showMessage && (
        <div className="message">
          这是一条重要消息
        </div>
      )}
      
      {/* 显示通知徽章 */}
      {hasNotifications && (
        <span className="badge">新</span>
      )}
      
      {/* 显示在线状态 */}
      {isOnline && (
        <div className="status-indicator online">
          在线
        </div>
      )}
      
      {/* 显示VIP标志 */}
      {isPremium && (
        <span className="vip-badge">VIP</span>
      )}
      
      {/* 显示认证标志 */}
      {isVerified && (
        <span className="verified-icon">✓ 已认证</span>
      )}
    </div>
  );
}

// 实际应用:用户卡片
function UserCard({ user }) {
  return (
    <div className="user-card">
      <img src={user.avatar} alt={user.name} />
      <h3>{user.name}</h3>
      <p>{user.email}</p>
      
      {user.isPremium && (
        <span className="badge premium">VIP会员</span>
      )}
      
      {user.isVerified && (
        <span className="badge verified">已验证</span>
      )}
      
      {user.isOnline && (
        <span className="online-indicator">在线</span>
      )}
      
      {user.bio && (
        <p className="bio">{user.bio}</p>
      )}
      
      {user.location && (
        <p className="location">📍 {user.location}</p>
      )}
    </div>
  );
}

1.3 逻辑与的短路特性

jsx
function ShortCircuitEvaluation() {
  const [count, setCount] = useState(0);
  const [enabled, setEnabled] = useState(true);
  
  return (
    <div>
      <p>计数:{count}</p>
      
      {/* count大于0时才显示 */}
      {count > 0 && <p>计数大于0</p>}
      
      {/* 链式条件:所有条件都要满足 */}
      {count > 0 && count < 10 && <p>计数在1-9之间</p>}
      
      {/* 多个条件组合 */}
      {enabled && count > 5 && count % 2 === 0 && (
        <p>已启用,计数大于5且为偶数</p>
      )}
      
      {/* 函数调用也适用 */}
      {enabled && performCheck() && (
        <p>检查通过</p>
      )}
      
      <button onClick={() => setCount(c => c + 1)}>增加</button>
      <button onClick={() => setEnabled(!enabled)}>
        {enabled ? '禁用' : '启用'}
      </button>
    </div>
  );
}

function performCheck() {
  console.log('执行检查');
  return true;
}

第二部分:常见陷阱

2.1 数字0的问题

jsx
// ❌ 问题:0会被渲染
function ZeroProblem({ count }) {
  return (
    <div>
      {/* 当count为0时,会在页面上显示"0" */}
      {count && <p>共 {count} 项</p>}
    </div>
  );
}

// ✅ 解决方案1:显式比较
function Solution1({ count }) {
  return (
    <div>
      {count > 0 && <p>共 {count} 项</p>}
    </div>
  );
}

// ✅ 解决方案2:布尔转换
function Solution2({ count }) {
  return (
    <div>
      {Boolean(count) && <p>共 {count} 项</p>}
    </div>
  );
}

// ✅ 解决方案3:双重否定
function Solution3({ count }) {
  return (
    <div>
      {!!count && <p>共 {count} 项</p>}
    </div>
  );
}

// ✅ 解决方案4:使用三元运算符
function Solution4({ count }) {
  return (
    <div>
      {count ? <p>共 {count} 项</p> : null}
    </div>
  );
}

// 实际应用示例
function ProductList({ products }) {
  return (
    <div>
      <h2>商品列表</h2>
      
      {/* 错误:products.length为0时显示0 */}
      {products.length && <p>共 {products.length} 个商品</p>}
      
      {/* 正确:使用显式比较 */}
      {products.length > 0 && <p>共 {products.length} 个商品</p>}
      
      {/* 或使用三元运算符 */}
      {products.length > 0 ? (
        <p>共 {products.length} 个商品</p>
      ) : (
        <p>暂无商品</p>
      )}
    </div>
  );
}

2.2 空字符串的问题

jsx
// ❌ 问题:空字符串是falsy值
function EmptyStringProblem({ text, title }) {
  return (
    <div>
      {/* text为空字符串时不显示 */}
      {text && <p>{text}</p>}
      
      {/* 但可能只是想显示空段落 */}
    </div>
  );
}

// ✅ 解决:检查非空
function EmptyStringSolution({ text }) {
  return (
    <div>
      {/* 检查trim后的长度 */}
      {text && text.trim() && <p>{text}</p>}
      
      {/* 或检查不为空字符串 */}
      {text !== '' && <p>{text}</p>}
      
      {/* 或使用可选链 */}
      {text?.trim() && <p>{text}</p>}
    </div>
  );
}

// 实际应用
function CommentSection({ comments }) {
  return (
    <div>
      {comments.map(comment => (
        <div key={comment.id}>
          <p>{comment.author}</p>
          
          {/* 评论内容可能为空,需要检查 */}
          {comment.text?.trim() && (
            <p className="comment-text">{comment.text}</p>
          )}
          
          {/* 回复数量,避免显示0 */}
          {comment.replies > 0 && (
            <span>{comment.replies} 条回复</span>
          )}
        </div>
      ))}
    </div>
  );
}

2.3 NaN和Infinity

jsx
function NaNInfinityHandling() {
  const [value, setValue] = useState(NaN);
  const [result, setResult] = useState(Infinity);
  
  return (
    <div>
      {/* NaN是falsy,不会渲染 */}
      {value && <p>值:{value}</p>}
      
      {/* Infinity是truthy,会渲染 */}
      {Infinity && <p>无限大</p>}
      
      {/* 正确检查NaN */}
      {!isNaN(value) && <p>有效值:{value}</p>}
      
      {/* 正确检查有限数 */}
      {isFinite(result) && <p>有限值:{result}</p>}
      
      {/* 组合检查 */}
      {!isNaN(value) && isFinite(value) && value > 0 && (
        <p>正数:{value}</p>
      )}
    </div>
  );
}

// 实际应用:计算器结果显示
function Calculator() {
  const [result, setResult] = useState(0);
  
  const divide = (a, b) => {
    const res = a / b;
    setResult(res);
  };
  
  return (
    <div>
      <button onClick={() => divide(10, 2)}>10 ÷ 2</button>
      <button onClick={() => divide(10, 0)}>10 ÷ 0</button>
      
      <div>
        结果:
        {isFinite(result) ? (
          <span>{result}</span>
        ) : (
          <span className="error">无效结果</span>
        )}
      </div>
    </div>
  );
}

2.4 undefined和null

jsx
function UndefinedNullHandling({ data }) {
  return (
    <div>
      {/* undefined和null都不会渲染 */}
      {undefined && <p>不会显示</p>}
      {null && <p>不会显示</p>}
      
      {/* 但要小心对象属性 */}
      {data && <p>{data.name}</p>}  {/* 如果data是null或undefined,不会报错 */}
      
      {/* 使用可选链更安全 */}
      {data?.name && <p>{data.name}</p>}
      
      {/* 检查属性是否存在 */}
      {data && 'name' in data && data.name && (
        <p>{data.name}</p>
      )}
    </div>
  );
}

第三部分:逻辑或运算符

3.1 基本用法

jsx
// 语法:value || fallback
// 如果value为falsy,返回fallback

function LogicalOr({ username, title, avatar, bio }) {
  return (
    <div>
      <h1>{title || '默认标题'}</h1>
      <p>用户:{username || '访客'}</p>
      <img src={avatar || '/default-avatar.png'} alt="头像" />
      <p>{bio || '这个人很懒,什么都没写'}</p>
    </div>
  );
}

// 实际应用:用户资料
function UserProfile({ user }) {
  return (
    <div className="user-profile">
      <h2>{user.name || '匿名用户'}</h2>
      <img src={user.avatar || '/default-avatar.png'} alt={user.name} />
      <p>{user.bio || '暂无简介'}</p>
      <p>邮箱:{user.email || '未设置'}</p>
      <p>电话:{user.phone || '未设置'}</p>
      <p>地址:{user.address || '未填写'}</p>
    </div>
  );
}

3.2 逻辑或的陷阱

jsx
// ❌ 问题:0和空字符串也会被替换
function OrProblem({ count, price, text }) {
  return (
    <div>
      {/* count为0时,显示"暂无"而不是0 */}
      <p>数量:{count || '暂无'}</p>
      
      {/* price为0时,显示"免费"而不是0 */}
      <p>价格:{price || '免费'}</p>
      
      {/* text为空字符串时,显示"无内容"而不是空 */}
      <p>内容:{text || '无内容'}</p>
    </div>
  );
}

// ✅ 解决:使用空值合并运算符??
function OrSolution({ count, price, text }) {
  return (
    <div>
      {/* count为0时,显示0 */}
      <p>数量:{count ?? '暂无'}</p>
      
      {/* price为0时,显示0(免费) */}
      <p>价格:{price === 0 ? '免费' : `¥${price}`}</p>
      
      {/* text为空字符串时,仍显示空字符串 */}
      <p>内容:{text ?? '无内容'}</p>
    </div>
  );
}

第四部分:空值合并运算符(??)

4.1 ??运算符详解

jsx
// 语法:value ?? fallback
// 只有value为null或undefined时,返回fallback
// 0、''、false都不会被替换

function NullishCoalescing({ count, text, flag, price }) {
  return (
    <div>
      {/* 0不会被替换 */}
      <p>数量:{count ?? '未设置'}</p>
      {/* count = 0 → 显示 "数量:0" */}
      {/* count = null → 显示 "数量:未设置" */}
      
      {/* 空字符串不会被替换 */}
      <p>文本:{text ?? '未设置'}</p>
      {/* text = '' → 显示 "文本:" */}
      {/* text = null → 显示 "文本:未设置" */}
      
      {/* false不会被替换 */}
      <p>标志:{String(flag ?? '未设置')}</p>
      {/* flag = false → 显示 "标志:false" */}
      {/* flag = null → 显示 "标志:未设置" */}
      
      {/* null和undefined会被替换 */}
      <p>{null ?? '默认值'}</p>  {/* 显示 "默认值" */}
      <p>{undefined ?? '默认值'}</p>  {/* 显示 "默认值" */}
    </div>
  );
}

// 实际应用:产品价格显示
function ProductCard({ product }) {
  return (
    <div className="product-card">
      <h3>{product.name}</h3>
      
      {/* 价格可能为0(免费)或null(未定价) */}
      <p className="price">
        {product.price === 0 
          ? '免费' 
          : product.price 
            ? `¥${product.price}` 
            : '价格待定'}
      </p>
      
      {/* 或使用?? */}
      <p className="price">
        {product.price ?? '价格待定'}
      </p>
      
      {/* 库存显示 */}
      <p className="stock">
        库存:{product.stock ?? '补货中'}
      </p>
      {/* stock = 0 → "库存:0" */}
      {/* stock = null → "库存:补货中" */}
    </div>
  );
}

4.2 ??vs||对比

jsx
function NullishVsOrComparison() {
  const values = {
    zero: 0,
    emptyString: '',
    false: false,
    null: null,
    undefined: undefined
  };
  
  return (
    <div>
      <h3>使用 ||(逻辑或)</h3>
      <p>0: {values.zero || '默认'}</p>              {/* 默认 */}
      <p>空字符串: {values.emptyString || '默认'}</p> {/* 默认 */}
      <p>false: {String(values.false || '默认')}</p>  {/* 默认 */}
      <p>null: {values.null || '默认'}</p>           {/* 默认 */}
      <p>undefined: {values.undefined || '默认'}</p>  {/* 默认 */}
      
      <h3>使用 ??(空值合并)</h3>
      <p>0: {values.zero ?? '默认'}</p>              {/* 0 */}
      <p>空字符串: {values.emptyString ?? '默认'}</p> {/* '' */}
      <p>false: {String(values.false ?? '默认')}</p>  {/* false */}
      <p>null: {values.null ?? '默认'}</p>           {/* 默认 */}
      <p>undefined: {values.undefined ?? '默认'}</p>  {/* 默认 */}
    </div>
  );
}

// React 19推荐使用??
function React19Recommendation({ data }) {
  return (
    <div>
      {/* ✅ 推荐:使用?? */}
      <p>数量:{data.count ?? 0}</p>
      <p>名称:{data.name ?? '未命名'}</p>
      <p>价格:{data.price ?? '待定'}</p>
      
      {/* ❌ 不推荐:使用||(除非确实要过滤falsy值) */}
      <p>数量:{data.count || 0}</p>
      {/* 如果count为0,会显示0(符合预期) */}
      {/* 但如果想区分0和null/undefined,就有问题 */}
    </div>
  );
}

第五部分:可选链运算符(?.)

5.1 基本用法

jsx
// 语法:object?.property
// 如果object是null或undefined,返回undefined
// 否则返回object.property

function OptionalChaining({ user }) {
  return (
    <div>
      {/* 传统方式:需要逐层检查 */}
      {user && user.profile && user.profile.avatar && (
        <img src={user.profile.avatar} alt="头像" />
      )}
      
      {/* 使用可选链:简洁明了 */}
      {user?.profile?.avatar && (
        <img src={user.profile.avatar} alt="头像" />
      )}
      
      {/* 数组可选链 */}
      {user?.friends?.[0]?.name && (
        <p>第一个好友:{user.friends[0].name}</p>
      )}
      
      {/* 函数可选链 */}
      {user?.getFullName?.() && (
        <p>全名:{user.getFullName()}</p>
      )}
    </div>
  );
}

// 实际应用:复杂数据展示
function UserDashboard({ userData }) {
  return (
    <div className="dashboard">
      <h2>{userData?.user?.name ?? '访客'}</h2>
      
      {/* 安全访问嵌套属性 */}
      {userData?.user?.profile?.bio && (
        <p>{userData.user.profile.bio}</p>
      )}
      
      {/* 数组长度检查 */}
      {(userData?.posts?.length ?? 0) > 0 && (
        <div>
          <h3>文章 ({userData.posts.length})</h3>
          {userData.posts.map(post => (
            <article key={post.id}>
              <h4>{post.title}</h4>
              {post?.content?.substring(0, 100)}...
            </article>
          ))}
        </div>
      )}
      
      {/* 方法调用 */}
      {userData?.user?.getPremiumStatus?.() && (
        <span className="premium">VIP会员</span>
      )}
    </div>
  );
}

5.2 可选链与空值合并组合

jsx
function CombinedOperators({ data }) {
  return (
    <div>
      {/* 结合使用?.和?? */}
      <p>名称:{data?.user?.name ?? '未命名'}</p>
      <p>年龄:{data?.user?.age ?? '未知'}</p>
      <p>邮箱:{data?.user?.email ?? '未设置'}</p>
      
      {/* 先用?.安全访问,再用??提供默认值 */}
      <p>城市:{data?.user?.address?.city ?? '未知城市'}</p>
      
      {/* 数组元素访问 */}
      <p>第一项:{data?.items?.[0]?.name ?? '无数据'}</p>
      
      {/* 方法调用结果 */}
      <p>状态:{data?.getStatus?.() ?? '未知'}</p>
    </div>
  );
}

第六部分:组合使用模式

6.1 多个&&组合

jsx
function MultipleAndConditions({ user, isPremium, hasAccess, isVerified }) {
  return (
    <div>
      {/* 所有条件都满足才显示 */}
      {user && isPremium && hasAccess && (
        <PremiumContent />
      )}
      
      {/* 链式判断对象属性 */}
      {user && user.profile && user.profile.avatar && (
        <img src={user.profile.avatar} alt="头像" />
      )}
      
      {/* 使用可选链简化 */}
      {user?.profile?.avatar && (
        <img src={user.profile.avatar} alt="头像" />
      )}
      
      {/* 复杂条件 */}
      {user && 
       isPremium && 
       isVerified && 
       user.credits > 100 && (
        <VIPFeatures />
      )}
      
      {/* 条件函数 */}
      {user && 
       checkPremiumStatus(user) && 
       checkAccessRights(user) && (
        <SpecialContent />
      )}
    </div>
  );
}

6.2 &&和??组合

jsx
function CombineAndNullish({ user, config, defaultTheme }) {
  return (
    <div>
      {/* 先判断存在,再提供默认值 */}
      {user && (
        <h2>{user.name ?? '匿名用户'}</h2>
      )}
      
      {/* 链式使用 */}
      <p>
        邮箱:{user && (user.email ?? '未设置')}
      </p>
      
      {/* 或使用可选链 */}
      <p>
        电话:{user?.phone ?? '未设置'}
      </p>
      
      {/* 配置值处理 */}
      {config && (
        <div className={config.theme ?? defaultTheme}>
          主题:{config.theme ?? '默认主题'}
        </div>
      )}
      
      {/* 数组元素 */}
      {user?.friends && (
        <p>
          好友数:{user.friends.length ?? 0}
        </p>
      )}
    </div>
  );
}

6.3 &&和三元运算符组合

jsx
function CombineAndTernary({ user, status }) {
  return (
    <div>
      {/* 简单条件用&& */}
      {user && <WelcomeMessage name={user.name} />}
      
      {/* 复杂条件用三元 */}
      {user ? (
        user.isPremium ? (
          <PremiumDashboard />
        ) : (
          <FreeDashboard />
        )
      ) : (
        <Login />
      )}
      
      {/* 组合使用 */}
      {status === 'loading' ? (
        <Spinner />
      ) : status === 'error' ? (
        <ErrorMessage />
      ) : user && (
        <UserContent user={user} />
      )}
    </div>
  );
}

第七部分:实战案例

7.1 案例1:条件导航菜单

jsx
function ConditionalNav({ user, permissions }) {
  const canViewDashboard = user && permissions.includes('dashboard');
  const canManageUsers = user && permissions.includes('manage_users');
  const canViewReports = user && permissions.includes('reports');
  const canAccessSettings = user && permissions.includes('settings');
  
  return (
    <nav>
      {/* 总是显示 */}
      <a href="/">首页</a>
      
      {/* 登录后显示 */}
      {user && <a href="/profile">个人资料</a>}
      
      {/* 有权限才显示 */}
      {canViewDashboard && <a href="/dashboard">仪表板</a>}
      {canManageUsers && <a href="/users">用户管理</a>}
      {canViewReports && <a href="/reports">报表</a>}
      {canAccessSettings && <a href="/settings">设置</a>}
      
      {/* VIP功能 */}
      {user?.isPremium && <a href="/premium">VIP专区</a>}
      
      {/* 管理员功能 */}
      {user?.role === 'admin' && <a href="/admin">管理后台</a>}
      
      {/* 登录/退出 */}
      {user ? (
        <button onClick={logout}>退出</button>
      ) : (
        <a href="/login">登录</a>
      )}
    </nav>
  );
}

7.2 案例2:数据加载状态

jsx
function DataDisplay({ loading, error, data }) {
  return (
    <div>
      {/* 加载状态 */}
      {loading && (
        <div className="loading">
          <Spinner />
          <p>加载中...</p>
        </div>
      )}
      
      {/* 错误状态 */}
      {error && (
        <div className="error">
          <p>加载失败:{error.message}</p>
          <button onClick={retry}>重试</button>
        </div>
      )}
      
      {/* 数据显示 */}
      {!loading && !error && data && (
        <div className="content">
          {data.length > 0 ? (
            <ul>
              {data.map(item => (
                <li key={item.id}>{item.name}</li>
              ))}
            </ul>
          ) : (
            <p className="empty">暂无数据</p>
          )}
        </div>
      )}
      
      {/* 或使用更清晰的条件 */}
      {!loading && !error && data?.length === 0 && (
        <EmptyState />
      )}
    </div>
  );
}

7.3 案例3:功能开关

jsx
function FeatureFlags({ features }) {
  return (
    <div>
      {/* 新功能开关 */}
      {features.enableNewUI && (
        <NewUIComponent />
      )}
      
      {/* 实验性功能 */}
      {features.experimental && (
        <ExperimentalFeature />
      )}
      
      {/* A/B测试 */}
      {features.variant === 'A' ? (
        <VariantA />
      ) : features.variant === 'B' ? (
        <VariantB />
      ) : (
        <DefaultVariant />
      )}
      
      {/* 组合条件 */}
      {features.enableChat && features.isPremium && (
        <PremiumChatFeature />
      )}
    </div>
  );
}

第八部分:最佳实践

8.1 选择合适的运算符

jsx
function OperatorSelection() {
  // ✅ 场景1:单一条件,无else → 使用&&
  {isLoggedIn && <WelcomeMessage />}
  
  // ✅ 场景2:二选一 → 使用三元运算符
  {isLoggedIn ? <Dashboard /> : <Login />}
  
  // ✅ 场景3:提供默认值(排除null/undefined)→ 使用??
  <p>{username ?? '访客'}</p>
  
  // ✅ 场景4:提供默认值(排除所有falsy)→ 使用||
  <p>{title || '无标题'}</p>
  
  // ✅ 场景5:安全访问嵌套属性 → 使用?.
  {user?.profile?.avatar && <img src={user.profile.avatar} />}
  
  // ✅ 场景6:多条件 → 提前返回或使用函数
  function renderContent() {
    if (loading) return <Spinner />;
    if (error) return <Error />;
    if (!data) return <Empty />;
    return <Content data={data} />;
  }
  
  return <div>{renderContent()}</div>;
}

8.2 避免复杂嵌套

jsx
// ❌ 不好:复杂的嵌套条件
function BadNesting({ user, loading, error }) {
  return (
    <div>
      {loading ? (
        <Spinner />
      ) : error ? (
        <Error />
      ) : user ? (
        user.isPremium ? (
          user.isActive ? (
            <PremiumDashboard />
          ) : (
            <InactiveNotice />
          )
        ) : (
          user.trialExpired ? (
            <TrialExpired />
          ) : (
            <FreeDashboard />
          )
        )
      ) : (
        <Login />
      )}
    </div>
  );
}

// ✅ 好:提前返回
function GoodEarlyReturn({ user, loading, error }) {
  if (loading) return <Spinner />;
  if (error) return <Error />;
  if (!user) return <Login />;
  if (!user.isActive) return <InactiveNotice />;
  if (user.isPremium) return <PremiumDashboard />;
  if (user.trialExpired) return <TrialExpired />;
  
  return <FreeDashboard />;
}

// ✅ 好:提取为独立组件
function GoodComponentSplit({ user, loading, error }) {
  function renderContent() {
    if (loading) return <Spinner />;
    if (error) return <Error />;
    if (!user) return <Login />;
    return <UserDashboard user={user} />;
  }
  
  return <div>{renderContent()}</div>;
}

function UserDashboard({ user }) {
  if (!user.isActive) return <InactiveNotice />;
  if (user.isPremium) return <PremiumDashboard />;
  if (user.trialExpired) return <TrialExpired />;
  return <FreeDashboard />;
}

8.3 性能考虑

jsx
function PerformanceConsiderations() {
  const [showExpensive, setShowExpensive] = useState(false);
  
  // ❌ 不好:即使不显示也会计算
  const expensiveValue = expensiveCalculation();
  
  return (
    <div>
      {showExpensive && <ExpensiveComponent value={expensiveValue} />}
    </div>
  );
  
  // ✅ 好:使用useMemo延迟计算
  const expensiveValue = useMemo(() => {
    if (!showExpensive) return null;
    return expensiveCalculation();
  }, [showExpensive]);
  
  return (
    <div>
      {showExpensive && <ExpensiveComponent value={expensiveValue} />}
    </div>
  );
  
  // ✅ 或者:直接在条件内计算
  return (
    <div>
      {showExpensive && <ExpensiveComponent value={expensiveCalculation()} />}
    </div>
  );
}

练习题

基础练习

  1. 使用&&实现条件渲染
  2. 避免0和空字符串的渲染问题
  3. 使用??提供默认值
  4. 使用?.安全访问嵌套属性

进阶练习

  1. 对比||、??和三元运算符的区别
  2. 实现复杂的条件组合渲染
  3. 重构嵌套的条件语句
  4. 优化条件渲染的性能

高级练习

  1. 实现一个权限控制系统,使用各种条件运算符
  2. 创建一个智能表单,根据条件显示/隐藏字段
  3. 实现功能开关系统(Feature Flags)

通过本章学习,你已经掌握了逻辑运算符在React中的完整应用。选择合适的运算符能让你的代码更加简洁、安全、高效。继续学习,成为React渲染专家!