开发者问题收集

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

2020-03-09
243

问题

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: Cannot read property 'length' of undefined

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

问题来源

感谢 @PompolutZ 的评论,错误的问题在于 index.js 中的第一个 <Container> 。由于它没有传递 modifier prop,因此 props.modifierprops.modifier.length 未定义。 container.js:22 被调用两次。第一次调用时,它是未定义的。

需要解决方案

根据 问题来源 ,我不知道区分传递 prop 的子组件(此处为 <Container> )和不传递 prop 的子组件的最佳实践是什么。我仍然想处理 prop,但如果有一个未传递 prop,我不希望 React 抛出错误。

2个回答

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

Container.defaultProps = {
  modifier: [],
}

另请参阅 React 文档 default Props 了解详情。

visionInc
2020-03-09

我会这样写(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>
  );
};
fxdxpz
2020-03-10