Gatsby:在组件中访问 props 数组的长度会导致 TypeError(属性未定义)

Posted

技术标签:

【中文标题】Gatsby:在组件中访问 props 数组的长度会导致 TypeError(属性未定义)【英文标题】:Gatsby: Accessing props array's length in a component leads to TypeError (property undefined) 【发布时间】:2020-06-21 18:45:06 【问题描述】:

问题

index.js 中,我将一个值为["fullWidth", "secondMod"]modifier 属性传递给了导入的Container 子组件:

index.js

<Container>
    <h1>Hi people</h1>
    <p>Welcome to your new Gatsby site.</p>
    <p>Now go build something great.</p>
</Container>

// Modifier Prop comes here
<Container modifier=["fullWidth", "secondMod"]>
    <Img fluid=data.placeholderImage.childImageSharp.fluid />
</Container>

container.js中,我想访问console.log中的数组:

container.js

import React from "react"
import PropTypes from 'prop-types';

// Styles
import container from "../styles/components/container.module.scss"

const Container = (props) => 
  console.log(props.modifier.length);   // TypeError: Cannot read property 'length' of undefined
  console.log(props.modifier);          // (2) ["fullWidth", "secondMod"]
  console.log(props.children.length);   // 3

  return (
    <section className=container.section>
      <div className=`$container.container $props.modifier`>
          props.children
      </div>
    </section>
  )


export default Container

尽管如此,第一个 console.log(props.modifier.length) 会引发错误。错误的页面标题是:

TypeError: 无法读取未定义的属性“长度”

相同,例如使用props.modifier[0]

问题根源

感谢@PompolutZ的评论,错误的问题是index.js中的第一个&lt;Container&gt;。因为它没有通过 modifier 属性,所以 props.modifierprops.modifier.length 是未定义的。

需要解决方案

根据问题来源,我不知道什么是区分传递道具和不传递道具的子组件(此处为&lt;Container&gt;)的最佳实践。我仍然想处理 props,但不希望 React 抛出错误,如果有一个没有通过 props。

【问题讨论】:

正如您正确评估的那样,您有该容器组件的两个实例,第一个没有修饰符道具,第二个带有修饰符道具。这就是为什么在第一个实例中访问修饰符长度时会出错,而第二个实例则一切正常。 啊,明白了。这是否意味着我必须运行 if-else 来检查是否传递了 modifier 属性以确保那些没有传递任何东西的 &lt;Container&gt;s 不会抛出错误?或者这里的最佳实践是什么? 【参考方案1】:

我会这样写(container.js):

import React from "react"
import PropTypes from 'prop-types';

// Styles
import container from "../styles/components/container.module.scss"

export default ( children, modifier = [] ) => 
  console.log(modifier && modifier.length);
  console.log(modifier && modifier);
  console.log(children && children.length);

  return (
    <section>
      <div>children</div>
    </section>
  );
;

【讨论】:

【参考方案2】:

使用defaultProps 可以防止 React 抛出错误。在这种情况下,这意味着在 const Container 的右括号 () 和 export default Container 之前将以下代码添加到 container.js

Container.defaultProps = 
  modifier: [],

另请参阅default Props 上的 React 文档。

【讨论】:

以上是关于Gatsby:在组件中访问 props 数组的长度会导致 TypeError(属性未定义)的主要内容,如果未能解决你的问题,请参考以下文章

如何访问子组件内部传递的prop数组

如何在 Gatsby 的模板组件中访问上下文变量?

重构 Gatsby 图像查询

VueJs 组件的 Prop 相关计算属性对对象数组 Prop 更改没有反应

Gatsby graphql 查询 GatsbyImage 以使用项目中的本地图像

对 vue.js 组件中的 props 进行操作