简体   繁体   English

有没有比添加 || 更好的解决方案 [ ] 在 ES6 中检查 null 的每个字段

[英]Is there a better solution than adding || [ ] to each field for a null check in ES6

I am working with a child component where an array item is passed as prop.我正在使用一个子component ,其中array项作为道具传递。 However, that item also contains another array where there should be null and undefined check before rendering.但是,该项目还包含另一个array ,其中应该有null和渲染前undefined的检查。 Adding || []添加|| [] || [] to each filed didn't seem the best way. || []到每个文件似乎都不是最好的方法。 Is there a better way that I am missing?我错过了更好的方法吗?

const ChildComponent= ({ newsItem, textColor, newsItemHeadingColor }) => {
  const imageFormats = newsItem?.itemImage?.formats;
  const imageSrc = useProgressiveImage({ formats: imageFormats });
  const history = useHistory();

  const { state } = useContextState();
  const { schemeMode, colorSchemes } = state;

  const { itemTagColor, itemTagTextColor } = getThemeColors({
    schemeMode,
    colorSchemes,
    colors: {
      itemTagColor: newsItem?.itemTagColor?.name,
      itemTagTextColor: newsItem?.itemTagTextColor?.name,
    },
  });

  return (
    <NewsItem
      onClick={() => {
        const url =
          newsItem?.itemTag === 'Lab'
            ? getPageLink({
                page: newsItem?.itemLink || [], <<<<<< this check
              })
            : newsItem?.itemLink || []; <<<<<< this check
        url && history.push(url);
      }}
    >
      <ImageContainer>
        <Image src={imageSrc} alt={`${newsItem?.itemImage || []}`} /> <<<<<< this check
      </ImageContainer>
      <NewsItemTag color={itemTagColor} itemTagTextColor={itemTagTextColor}>
        <Body4>{`${newsItem?.itemTag || []}`}</Body4>               <<<<<< this check
      </NewsItemTag>
      <NewsItemName newsItemHeadingColor={newsItemHeadingColor}>{`${
        newsItem?.itemTitle || []                                     <<<<<< this check
      }`}</NewsItemName>
      <Description textColor={textColor}>{`${
        (newsItem.description &&
          newsItem?.itemDescription) || []                          <<<<<< this check
      }`}</Description>
    </NewsItem>
  );
};

In fact yes, you have many many ways for improving your code and the readabilty of it.事实上是的,你有很多方法来改进你的代码和它的可读性。

In your <NewItem /> onClick function:在您的<NewItem /> onClick function 中:

  • I have nothing to say for the first one, it seems correct since you want the item link or an empty array第一个我无话可说,这似乎是正确的,因为您想要项目链接或空数组
  • For the second one, your are already using the optional chaining operator , the "?".对于第二个,您已经在使用optional chaining operator “?”。 This operator check if there is a value, if not, it returns null .该运算符检查是否有值,如果没有,则返回null That means that should be enough, since you check after your url variable is defined or not.这意味着这应该足够了,因为您在url变量是否定义之后进行检查。 So simply write that: : newsItem?.itemLink所以简单地写: newsItem?.itemLink

For the third one, the one on your <Image /> component, First there is no need at all to put everything in backquote.对于第三个,即<Image />组件上的那个,首先根本不需要将所有内容都放在反引号中。 Simply alt={newsItem?.itemImage || []}简单alt={newsItem?.itemImage || []} alt={newsItem?.itemImage || []} should work fine. alt={newsItem?.itemImage || []}应该可以正常工作。 Then, alt attribute is taking a string, so maybe change it with alt={newsItem?.itemImage || ""}然后, alt attribute是一个字符串,所以可以用alt={newsItem?.itemImage || ""}更改它alt={newsItem?.itemImage || ""}

For the three last one, they are basically the same, you have content to display and you want to display nothing if there are empty.最后三个,基本一样,有内容要显示,有空就什么也不显示。 The fact here is that your are rendering some elements even if there is no content and this is not an optimized way.这里的事实是,即使没有内容,您也正在渲染一些元素,这不是一种优化的方式。 The cleanest way in my opinion in order to make your template more readable will be to define variable before your return function and based on this variable, you will display the appropriate section:在我看来,为了使您的模板更具可读性,最简洁的方法是在您return function之前定义变量,并基于此变量,您将显示相应的部分:

Before your return function:在您返回 function 之前:

const hasTag = !!newsItem?.itemTag;
const hasTitle = !!newsItem?.itemTitle;
const hasDescription = !!newsItem.description && !!newsItem?.itemDescription;

In your template:在您的模板中:

 {hasTag && <NewsItemTag color={itemTagColor} itemTagTextColor={itemTagTextColor}> <Body4>{newsItem.itemTag}</Body4> </NewsItemTag>} {hasTitle && <NewsItemName newsItemHeadingColor={newsItemHeadingColor}> {newsItem.itemTitle} </NewsItemName> {hasDescription && <Description textColor={textColor}> {newsItem.itemDescription} </Description>

I hope this was clear, hit me up if this wasn't.我希望这很清楚,如果不是,请打我。

Happy coding:)快乐编码:)

There are multiple ways that you could handle this in javascript, assume that we have a component that receives a prop called newsItem which is an object有多种方法可以在 javascript 中处理此问题,假设我们有一个组件接收名为newsItem的道具,该道具是 object

You could do that in the following ways您可以通过以下方式做到这一点

  • Using the logical operator or (es6)使用逻辑运算符 or (es6)
 const itemLinks = newsItem.links || [] 

you dont need the optional chaining operator (?.) here if you know that newsItem is an object and not undefined .如果您知道 newsItem 是object而不是undefined ,则此处不需要可选的链接运算符(?.)

This is the shortest syntax, and it works fine as long as links is either undefined or an array however it becomes problematic if later links become a boolean variable, which will yield incorrect results This method is not safe, and it becomes cumbersome to handle as properties become nested deeply这是最短的语法,只要linksundefined的或array ,它就可以正常工作,但是如果后面的links变成boolean变量,就会出现问题,这将产生不正确的结果 这种方法不安全,而且处理起来很麻烦属性变得嵌套很深

  • Using lodash get method or some other library or a custom solution (es6)使用 lodash get 方法或其他一些库或自定义解决方案 (es6)

because in es6 the only practical way was to either the logical operator and this was a common problem, custom solutions were brought it, basically any solution should have two advantages over the logical or operator因为在 es6 中唯一实用的方法是使用逻辑运算符,这是一个常见问题,因此带来了自定义解决方案,基本上任何解决方案都应该比逻辑或运算符具有两个优势

  1. They should work fine with boolean values它们应该与 boolean 值一起正常工作

  2. They should be easier to work with deeply nested values它们应该更容易处理深度嵌套的值

custom someDeepleyNested = get(newsItem, 'property1.property2.property3', 'defaultValue')
// there is no need for property1, property2, property3 to exist at all

Because this was a common problem for all javascript developers,the language had to bring a native solution因为这是所有 javascript 开发者的通病,所以语言必须自带原生解决方案

const someNestedProperty = newsItem?.property1?.property2?.property3 ?? 'someDefaultValue'

// notice that both the Optional chaining operator and Nullish coalescing Operator, work with both undefined and null
  • Specific to react: use default props具体到react:使用默认props
const Component = ({newsLink}) => {}
Component.defaultProps = {
 newsItem: {
    itemLinks: []
 }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM