如何避免代码中出现嵌套的三元表达式?

How can I avoid nested ternary expressions in my code?

我有这样的代码。如何使用 JavaScript 中的函数式编程以更简洁、更优雅的方式编写它?我想摆脱嵌套的三元表达式。有什么想法吗?

props => ({
            iconColor: props.isPriority ? (props.isCompleted ? variables.color.lightpurple : variables.color.purple ) : variables.color.gray3,
            iconName: props.isPriority ? 'star-full' : 'star-empty',
          }))

这是该代码的其余部分:

编辑:

const enhance: React$HOC<*, InitialProps> = compose(
      withProps(props => ({
        iconColor: props.isPriority ? (props.isCompleted ? variables.color.lightpurple : variables.color.purple) : variables.color.gray3,
        iconName: props.isPriority ? 'star-full' : 'star-empty',
      }))
    )

我同意@JaromandaX关于使用函数的观点。这让你的 JSX 保持干净,你的逻辑可重用。

除此之外,为了避免嵌套的三元运算符,您可以尝试这样的操作:

  • 保留所有可能值的 array/map
  • 根据标志,创建一个二进制字符串并将其转换为数字。
  • return 提供索引处的值

function withTernary(a, b){
  return a ? (b ? 'test': 'foo') : 'bar';
}

function withoutTernary(a, b){
  var result = ['bar', undefined, 'foo', 'test'];
  // or may be a map
  /*
  * map = {
  *    '00': 'bar',
  *    '10': 'foo',
  *    '11': 'test'
  * }
  */
  var index = parseInt((+a) + '' + (+b), 2);
  return result[index];
}

var testCase = [[0,0], [1, 0], [1,1]];

testCase.forEach(x => {
  console.log('With Ternary:', withTernary(...x));
  console.log('Without Ternary:', withoutTernary(...x));
})

可以使用 IIaFE(立即调用箭头函数表达式):

props => ({
        iconColor:(_=>{
           if(props.isPriority){
             if(props.isCompleted){
               return variables.color.lightpurple;
             }
             return variables.color.purple;
           }
           return variables.color.gray3;
        })(),
        iconName:(_=>{ 
           if(props.isPriority){
              return 'star-full';
           }
           return 'star-empty';
       })()
}))

Yes, but my linter is not happy: 44:16 error Do not nest ternary expressions [no-nested-ternary]

如果这是您唯一的问题,那么解决方案很简单。创建您自己的条件函数:

const iff = (condition, then, otherwise) => condition ? then : otherwise;

props => ({
  iconColor: props.isPriority ?
    iff(props.isCompleted, variables.color.lightpurple, variables.color.purple) :
    variables.color.gray3,
  iconName: props.isPriority ? 'star-full' : 'star-empty',
})

现在你的 linter 不应该抱怨了。话虽如此,您应该在 linter 中禁用 [no-nested-ternary]。你的 linter 认为嵌套条件语句不好,这有点愚蠢。

在这种情况下,您可以考虑反转条件以删除 "unnatural" 三元组嵌套。仍然会有嵌套,但它可以写成平面 - 没有括号 - 这意味着你可以将它整齐地排列在多行中:

props => ({
    iconColor:
        !props.isPriority ? variables.color.gray3
        : props.isCompleted ? variables.color.lightpurple
        : variables.color.purple,
    iconName: props.isPriority ? 'star-full' : 'star-empty',
})

这样做的缺点是使用了负面条件,我通常会尽量避免这种情况,因为它们比正面条件更难遵循。

另一种选择是使用 &&:

将条件展平
props => ({
    iconColor:
        props.isPriority && props.isCompleted ? variables.color.lightpurple
        : props.isPriority ? variables.color.purple
        : variables.color.gray3,
    iconName: props.isPriority ? 'star-full' : 'star-empty',
})