如何在 react 中使用 if-elseif-else 多重条件判断
侧边栏壁纸
  • 累计撰写 1,061 篇文章
  • 累计收到 0 条评论

如何在 react 中使用 if-elseif-else 多重条件判断

加速器之家
2024-10-20 / 0 评论 / 2 阅读 / 正在检测是否收录...

使用过 Vue 的同学们都知道,在 Vue 中有v-if, v-elseifv-else的语法糖,方便我们进行流程控制。但 react 中使用的 jsx,并没有这些语法糖,而是使用一些其他方式来实现条件控制的。

1. react 中的条件渲染 #

在 react 中有多种实现条件渲染的方式,我们每个稍微介绍一下。

1.1 与运算符&& #

当前面的表达式为真时,则执行后面的表达式。相当于if

// 当showModal变量为真时,则渲染弹窗,否则不显示
{showModal && <Modal>Modal>}

这里需要注意的是,当使用长度来控制的时候,要使用判断表达式,而不是直接用.length来判断,

// 要判断length>0,若只用list.length判断时,最后会渲染出来一个0
{list.length > 0 && <Modal>Modal>}

1.2 三目运算 #

当需要非黑即白时,这里就用到了三目运算。相当于if-else

{list.length>0 ? `您一共有${list..length}条数据` : '您暂时还没有数据'}

1.3 立即执行或者单独的方法渲染 #

当需要更复杂的判断时,例如 3 个及以上的情况,或者多个判断条件时,即if-elseif-else的类型时,情况就稍微复杂一些。不过我们依然也有多种方式来实现。

  1. 多个嵌套的三目运算;
  2. 立即执行方法;
  3. 单独的方法;

1.3.1 多个嵌套的三目运算 #

嵌套的三目运算,也能作为多个 if 判断,但看起来实现逻辑有点乱:

const Home = () => {
  return <div>{A ? <>a right : B ? <>b right : <>else}
; };

1.3.2 立即执行 #

const Home = () => {
  return (<div>
{
(() => {
if (A) {
return <>a right
} if (B) { return <>b right } return <>else })(); }
); }

1.3.3 单独的方法 #

const Home = () => {
  const projectStatus = 1;
  const renderItem = (item) => {
    if (projectStatus !== 1) {
      return <button>活动暂未开始或已结束button>;
    }
    if (item.status === 1) {
      return <button>点击参与button>;
    }
    return <button>已无库存button>;
  };

  return <div>{list.map((item) => renderItem(item))}div>;
};

立即执行方法和单独的方法,都把判断逻辑进行了割裂。如果我依然想在 render 中的 jsx 中,写判断怎么办呢?

2. 新的方式 #

这里我一直想着用 Vue 中的方式一样,无需将条件判断独立出来,而是直接在顺着整体的思路往下写。这里我就封装了一个if-elseif-else的组件。

2.1 调用方式 #

先看下使用方式,然后再看代码实现。

import { When, Case } from './when';

const Home = () => {
  return (
    <div className="btn-container">
<When>
<Case if={status === 0 || status === 2}>
<Button className="donate-btn-common cant-donate-hotvalue">
{status === 0 ? '活动还未开始' : '活动已结束'}
Button>

Case>
<Case elseif={projectState.process >= 100}>
<Button className="donate-btn-common cant-donate-hotvalue">该项目已捐满Button>
Case>
<Case else>
<Button loading={btnLoading} className="donate-btn-common donate-hotvalue" onClick={handleDonateClick}>
捐热力值帮助TA
Button>
Case>
When>
div> ); };

这里用When进行包装,然后每个Case对应 1 个判断条件,从上往下,若某个为真,则直接渲染 children 中的内容,否则接着往下判断,直到最后。

这样实现起来,流程也比较顺,然后条件判断也很清晰。

2.2 代码实现 #

我们在这里直接贴代码,看看是怎么实现的:

import React from 'react';

const isArray = (arg: any): boolean => {
  if (Array.isArray) {
    return Array.isArray(arg);
  }
  return Object.prototype.toString.call(arg) === '[object Array]';
};

interface CaseProps {
  if?: boolean;
  elseif?: boolean;
  else?: boolean;
  children: JSX.Element | JSX.Element[];
}

export const Case = (props: CaseProps) => {
  return <>{props.children};
};

export const When = ({ children }: { children: any }): JSX.Element | null => {
  if (!children) {
    return null;
  }

  let schildren: any = [];
  if (isArray(children)) {
    // 当存在多个case节点时,children为数组
    schildren = children;
  } else {
    // 当只有一个case节点,children为object类型
    schildren.push(children);
  }
  // 判断所有的子节点是不是Case类型
  schildren.forEach((child: any) => {
    if (!child.type || child.type.name !== Case.name) {
      throw new Error('the children of component When muse be component Case');
    }
  });
  // 查找if的节点,若有则直接返回
  const ifChildren = schildren.filter((item: any) => item.props.if);
  if (ifChildren.length) {
    return <>{ifChildren};
  }
  // 再查找elseif的节点
  const elseIfChildren = schildren.filter((item: any) => item.props.elseif);
  if (elseIfChildren.length) {
    // 这里只输出第1个为true的组件
    return <>{elseIfChildren[0]};
  }
  // 返回其他的节点
  return <>{schildren.filter((item: any) => item.props.else)};
};

最终实现起来也非常的简单,按照顺序查找相应的属性,然后进行返回即可。

3. 总结 #

在 react 中,条件判断的方式有很多,官方的文档就介绍了很多种,但要实现一些稍微复杂点的条件判断时,就会让代码显得很凌乱。这里我也就实现实现了一套多重判断的机制。

机制如我

0

评论

博主关闭了当前页面的评论