【问题标题】:Using a ternary operator for inline styling with >2 conditions with React js [closed]使用三元运算符进行具有> 2个条件的内联样式和React js [关闭]
【发布时间】:2020-12-25 23:27:33
【问题描述】:

我有一个要映射的数据数组,我想根据数组中每个对象的两个项目的比较来设置三种颜色之一的卡片元素。代码如下所示:

data.map(item => {
 return (
  //some code
  <Card className={
   item.someNumber > item.anotherNumber*1.05 ?
   classes.orange :
   item.someNumber < item.anotherNumber*.95 ?
   classes.blue :
   classes.grey}
   >
  //more code

这似乎有效(即我所有的卡片都按预期着色),但我的问题是,这是“坏代码”吗?我真的找不到明确的答案或类似的解决方案(可能我没有问正确的问题);我确实尝试在渲染的代码上方使用 if/else 语句创建函数,但由于我们如何映射数据以及颜色基于数组中每个对象内的比较这一事实,我无法弄清楚弄清楚如何使其他任何事情都起作用。

【问题讨论】:

  • 你说。在我看来,任何超过两种情况的三元运算符都不利于可读性。
  • 你为什么不写一个包含这个逻辑的方法(以更易读的方式)并返回正确的类名?
  • @PrateekThapa 实际上我是唯一一个阅读这段代码的人,所以如果可读性是唯一的潜在问题,那么我可以接受它的现状。
  • @AndréFrings 问题之一是我要返回多张卡片,其中包含来自数组的不同数据,因此尝试按照您建议的方式编写方法变得很棘手(我确实尝试了几次小时)。

标签: reactjs material-ui conditional-operator


【解决方案1】:

在这种情况下,我认为它归结为偏好和可读性。如果您是该项目的唯一工作人员,并且您发现嵌套三元组很容易推理,我认为您发布的代码是表达该逻辑的简洁方式。

就我个人而言,我发现嵌套三元组很难阅读,所以即使需要多几行代码,我也会找到一种不同的方式来表达这种逻辑。

以下是您可能需要考虑的一些替代解决方案:

  1. 将选择逻辑移到道具之外
data.map(item => {
 let className = classes.grey;
 if (item.someNumber > item.anotherNumber*1.05) {
  className = classes.orange;
 } else if (item.someNumber < item.anotherNumber*.95) {
  className = classes.blue;
 }

 return (
  //some code
  <Card className={className}>
  //more code
})
  1. 将选择逻辑移动到函数中
const getClassName = item => {
 if (item.someNumber > item.anotherNumber*1.05) {
  return classes.orange;
 } else if (item.someNumber < item.anotherNumber*.95) {
  return classes.blue;
 } else {
  return classes.grey;
 }
};

data.map(item => {
 return (
  //some code
  <Card className={getClassName(item)}>
  //more code
})
  1. 在我看来,您列出的 3 个案例可能是互斥的(即前两个条件不可能同时为真),在这种情况下,您可以使用像 classnames 这样的辅助库来执行这个逻辑。
import cx from 'classnames';

data.map(item => {
 const className = {
  [classes.orange]: item.someNumber > item.anotherNumber*1.05,
  [classes.blue]: item.someNumber < item.anotherNumber*.95,
  [classes.grey]: item.someNumber >= item.anotherNumber*.95 && item.someNumber <= item.anotherNumber*1.05
 };

 return (
  //some code
  <Card className={cx(className)}>
  //more code
})

由您决定其中任何一个是否比您当前拥有的“更好”或更易读。如果你和队友一起工作,我也会征求他们的意见,因为你们都将努力维护相同的代码。

【讨论】:

  • 感谢您的所有建议!我是唯一一个编写此代码的人,并且可能因为我的大脑很奇怪,我不觉得三元运算符中的多个条件难以阅读。 :) 但我会研究其他选项 - 大多数情况下,我只是想确保我没有编写最终会破坏某些东西的代码。再次感谢!
【解决方案2】:

您还可以创建一个包含您的 classNames 逻辑的函数,然后在元素的 className 属性中调用它。见例子:

const classLogic = () => {
  if (someCondition == true) {
    return "class-1";
  } else {
    return "class-2";
  }
};

<Card className={classLogic()} ></Card>

【讨论】:

  • 这实际上是我最初尝试的,但我实际上有 6 张卡片,每张卡片返回不同的数据并且有不同的样式要求(我知道,烦人;))。不过谢谢你的建议!
【解决方案3】:

我使用这个库有条件地将类名连接在一起https://github.com/JedWatson/classnames。使用它你可以摆脱样板代码(如果你创建另一个返回类名的函数),你只需要关注条件和类名。

【讨论】:

    猜你喜欢
    • 2011-05-06
    • 1970-01-01
    • 2018-02-06
    • 2018-04-29
    • 2020-08-21
    • 1970-01-01
    • 2015-02-15
    • 1970-01-01
    • 2016-11-02
    相关资源
    最近更新 更多