【问题标题】:Passing a prop to a child from parent with React and Gatsby使用 React 和 Gatsby 从父母那里将道具传递给孩子
【发布时间】:2019-06-01 08:57:00
【问题描述】:

Gatsby 新手在这里,所以请耐心等待我。我正在使用 Gatsby 和 React 构建一个非常基本的博客应用程序。我有一个登录页面,其中有一个显示最新发布的 3 篇博客文章的部分。到目前为止,我的index.js 文件中的以下代码一切正常:

import React from 'react'
import { Link, graphql } from 'gatsby'
import get from 'lodash/get'

import Bio from '../components/Bio'
import Layout from '../components/Layout'
import SEO from '../components/SEO'
import { formatReadingTime } from '../utils/helpers'

class BlogIndex extends React.Component {
  render() {
    const siteTitle = get(this, 'props.data.site.siteMetadata.title')
    const siteDescription = get(
      this,
      'props.data.site.siteMetadata.description'
    )
    const size = 3
    const posts = get(this, 'props.data.allMarkdownRemark.edges')

    return (
        <div className="container">
          <Layout location={this.props.location} title={siteTitle}>
            <SEO />
            <Bio />
            <section>
              <div>
                {posts.slice(0, size).map(({ node }) => {
                  const title = get(node, 'frontmatter.title') || node.fields.slug
                  return (
                    <div key={node.fields.slug}>
                      <h3>
                        <Link to={node.fields.slug}>
                          {title}
                        </Link>
                      </h3>
                      <p>
                        {node.frontmatter.date}
                        {` • ${formatReadingTime(node.timeToRead)}`}
                      </p>
                      <p
                        dangerouslySetInnerHTML={{ __html: node.frontmatter.spoiler }}
                      />
                    </div>
                  )
                })}
              </div>
            </section>
          </Layout>
        </div>
    )
  }
}

export default BlogIndex

export const pageQuery = graphql`
  query {
    site {
      siteMetadata {
        title
        description
      }
    }
    allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
      edges {
        node {
          fields {
            slug
          }
          timeToRead
          frontmatter {
            date(formatString: "MMMM DD, YYYY")
            title
            spoiler
          }
        }
      }
    }
  }
`

但是,我想将最新的博客文章部分分成一个单独的组件(例如LatestBlogPosts.js)并将其导入我的index.js 文件中。因此,我将标记复制到一个单独的文件中,将该文件导入我的index.js 中,突然出现错误提示:

TypeError: Cannot read property 'slice' of undefined

我从新创建的文件中检查并记录posts 也返回undefinedLatestBlogPosts.js 文件如下所示:

import React from 'react'
import { Link } from 'gatsby'
import {formatReadingTime} from "../utils/helpers";
import get from 'lodash/get'

class LatestBlogPosts extends React.Component {
  render() {
    const size = 3
    const posts = get(this, 'props.data.allMarkdownRemark.edges')

    return (
      <section>
        <div>
          {posts.slice(0, size).map(({ node }) => {
            const title = get(node, 'frontmatter.title') || node.fields.slug
            return (
              <div key={node.fields.slug}>
                <h3>
                  <Link to={node.fields.slug}>
                    {title}
                  </Link>
                </h3>
                <p>
                  {node.frontmatter.date}
                  {` • ${formatReadingTime(node.timeToRead)}`}
                </p>
                <p
                  dangerouslySetInnerHTML={{ __html: node.frontmatter.spoiler }}
                />
              </div>
            )
          })}
        </div>
      </section>
    )
  }
}

export default LatestBlogPosts

而修改后的index.js 看起来像这样:

import React from 'react'
import { Link, graphql } from 'gatsby'
import get from 'lodash/get'

import Bio from '../components/Bio'
import Layout from '../components/Layout'
import SEO from '../components/SEO'
import Footer from '../components/Footer'
import { formatReadingTime } from '../utils/helpers'
import { rhythm } from '../utils/typography'
import LatestBlogPosts from "../components/LatestBlogPosts";

class BlogIndex extends React.Component {
  render() {
    const siteTitle = get(this, 'props.data.site.siteMetadata.title')
    const siteDescription = get(
      this,
      'props.data.site.siteMetadata.description'
    )

    return (
        <div className="container-fluid">
          <Layout location={this.props.location} title={siteTitle}>
            <SEO />
            <Bio />
            <LatestBlogPosts />
            <Footer />
          </Layout>
        </div>
    )
  }
}

export default BlogIndex

export const pageQuery = graphql`
  query {
    site {
      siteMetadata {
        title
        description
      }
    }
    allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
      edges {
        node {
          fields {
            slug
          }
          timeToRead
          frontmatter {
            date(formatString: "MMMM DD, YYYY")
            title
            spoiler
          }
        }
      }
    }
  }
`

我似乎无法理解为什么postsLatestBlogPosts.js 文件中返回undefined

【问题讨论】:

  • 您没有将帖子传递给子组件,如果您不想这样做,那么您也不会在子组件中获取帖子。其中之一应该可以为您解决问题。
  • 也就是说,只需将posts 作为道具传递给&lt;LatestBlogPosts /&gt;

标签: javascript reactjs gatsby


【解决方案1】:

您没有将posts 传递给LatestBlogPosts。试试:

&lt;LatestBlogPosts posts={posts} /&gt;

然后在LatestBlogPosts 中,您可以使用this.props.posts 访问。

【讨论】:

    【解决方案2】:

    问题在于这个表达式:

    posts = get(this, 'props.data.allMarkdownRemark.edges')
    

    在您的第一个示例中,this 指向 BlogIndex;在第二个示例中,您已将表达式移至 LatestBlogPostsrender() 方法,因此表达式将查找该组件上的数据。

    您需要将帖子作为道具传递给子组件:

    <LatestBlogPosts posts={posts} />
    

    并在孩子的render方法中引用:

    {this.props.posts.slice(...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-31
      相关资源
      最近更新 更多