[英]Passing a prop to a child from parent with React and Gatsby
Gatsby newbie in here, so be patient with me. 盖茨比新手在这里,请耐心等待我。 I'm building a very basic blog app with Gatsby and React.
我正在用Gatsby和React构建一个非常基本的博客应用程序。 I have a landing page with a section where I display the latest 3 blog posts that were published.
我有一个登录页面,其中包含一个部分,其中显示了最新发布的3篇博客文章。 Until now, everything worked fine with the following code in my
index.js
file: 到目前为止,我的
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
}
}
}
}
}
`
However, I would like to separate the latest blog posts section into a separate component (ex. LatestBlogPosts.js
) and import it in my index.js
file. 但是,我想将最新的博客文章部分分成一个单独的组件(例如,
LatestBlogPosts.js
)并将其导入到我的index.js
文件中。 Therefore, I copied the markup in a separate file, imported that file in my index.js
and all of a sudden there is an error saying: 因此,我将标记复制到一个单独的文件中,然后将该文件导入到
index.js
,突然出现一个错误:
TypeError: Cannot read property 'slice' of undefined
I checked and logging posts
from the newly created file also returns undefined
. 我检查和记录
posts
来自新创建的文件也将返回undefined
。 The LatestBlogPosts.js
file looks like this: LatestBlogPosts.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
And the modified index.js
looks like this: 修改后的
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
}
}
}
}
}
`
I can't seem to understand why posts
returns undefined
in the LatestBlogPosts.js
file? 我似乎无法理解为什么
posts
在LatestBlogPosts.js
文件中返回undefined
?
The problem lies in this expression: 问题在于此表达式:
posts = get(this, 'props.data.allMarkdownRemark.edges')
In your first example, this
points to BlogIndex
; 在您的第一个示例中,
this
指向BlogIndex
; in your second example, you've moved the expression to the render()
method of LatestBlogPosts
, so the expression will look for the data on that component. 在第二个示例中,您已将表达式移动到
LatestBlogPosts
的render()
方法,因此表达式将在该组件上查找数据。
You need to pass the posts to the child component as a prop: 您需要将这些帖子作为道具传递给子组件:
<LatestBlogPosts posts={posts} />
And reference it in the child's render method: 并在孩子的render方法中引用它:
{this.props.posts.slice(...
You're not passing posts
to LatestBlogPosts
. 您没有将
posts
传递到LatestBlogPosts
。 Try: 尝试:
<LatestBlogPosts posts={posts} />
then in LatestBlogPosts
you can access with this.props.posts
. 然后在
LatestBlogPosts
您可以使用this.props.posts
访问。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.