Я добавляю реквизит компонента Sidebar к моему шаблону.
Я передаю {... this.props} на боковую панель.Но это все равно приводит к TypeError: Cannot read property 'map' of undefined in my Menu file.
Моему PostTemplateDetails
файлу, к которому я хочу добавить компонент боковой панели:
import React from 'react'
import Sidebar from '../Sidebar'
import { Link } from 'gatsby'
import moment from 'moment'
import './style.scss'
class PostTemplateDetails extends React.Component {
render() {
const { subtitle, author } = this.props.data.site.siteMetadata
const post = this.props.data.markdownRemark
const tags = post.fields.tagSlugs
const tagsBlock = (
<div className="post-single__tags">
<ul className="post-single__tags-list">
{tags &&
tags.map((tag, i) => (
<li className="post-single__tags-list-item" key={tag}>
<Link to={tag} className="post-single__tags-list-item-link">
{post.frontmatter.tags[i]}
</Link>
</li>
))}
</ul>
</div>
)
return (
<div>
<Sidebar {...this.props} />
<div className="content">
<div className="content__inner">
<div className="post-single">
<div className="post-single__inner">
<h1 className="post-single__title">{post.frontmatter.title}</h1>
<div
className="post-single__body"
/* eslint-disable-next-line react/no-danger */
dangerouslySetInnerHTML={{ __html: post.html }}
/>
<div className="post-single__date">
<em>
Published {moment(post.frontmatter.date).format('D MMM YYYY')}
</em>
</div>
</div>
<div className="post-single__footer">
{tagsBlock}
<hr />
<p className="post-single__footer-text">
{subtitle}
<a
href={`https://twitter.com/${author.twitter}`}
target="_blank"
rel="noopener noreferrer"
>
<br /> <strong>{author.name}</strong> on Twitter
</a>
</p>
</div>
</div>
</div>
</div>
</div>
)
}
}
export default PostTemplateDetails
Файл компонента моей боковой панели:
import React from 'react'
import get from 'lodash/get'
import { Link } from 'gatsby'
import Menu from '../Menu'
import Links from '../Links'
import profilePic from '../../pages/photo.jpg'
import './style.scss'
class Sidebar extends React.Component {
render() {
const { location } = this.props
const {
author,
subtitle,
copyright,
menu,
} = this.props.data.site.siteMetadata
const isHomePage = get(location, 'pathname', '/') === '/'
/* eslint-disable jsx-a11y/img-redundant-alt */
const authorBlock = (
<div>
<Link to="/">
<img
src={profilePic}
className="sidebar__author-photo"
width="75"
height="75"
alt={author.name}
/>
</Link>
{isHomePage ? (
<h1 className="sidebar__author-title">
<Link className="sidebar__author-title-link" to="/">
{author.name}
</Link>
</h1>
) : (
<h2 className="sidebar__author-title">
<Link className="sidebar__author-title-link" to="/">
{author.name}
</Link>
</h2>
)}
<p className="sidebar__author-subtitle">{subtitle}</p>
</div>
)
/* eslint-enable jsx-a11y/img-redundant-alt */
return (
<div className="sidebar">
<div className="sidebar__inner">
<div className="sidebar__author">{authorBlock}</div>
<div>
<Menu data={menu} />
<Links data={author} />
<p className="sidebar__copyright">{copyright}</p>
</div>
</div>
</div>
)
}
}
export default Sidebar
Файл компонента «Мое меню», который добавляется в файл компонента «Боковая панель» - именно здесь, по-видимому, и находится ошибка.
import React from 'react'
import { Link } from 'gatsby'
import './style.scss'
class Menu extends React.Component {
render() {
const menu = this.props.data
const menuBlock = (
<ul className="menu__list">
{menu.map(item => (
<li className="menu__list-item" key={item.path}>
<Link
to={item.path}
className="menu__list-item-link"
activeClassName="menu__list-item-link menu__list-item-link--active"
>
{item.label}
</Link>
</li>
))}
</ul>
)
return <nav className="menu">{menuBlock}</nav>
}
}
export default Menu
Я не уверен, почему это не работает, так как добавление в мой PAGETemplateDetails
файл работает нормально:
import React from 'react'
import Sidebar from '../Sidebar'
import './style.scss'
class PageTemplateDetails extends React.Component {
render() {
const page = this.props.data.markdownRemark
return (
<div>
<Sidebar {...this.props} />
<div className="content">
<div className="content__inner">
<div className="page">
<h1 className="page__title">{page.frontmatter.title}</h1>
<div
className="page__body"
/* eslint-disable-next-line react/no-danger */
dangerouslySetInnerHTML={{ __html: page.html }}
/>
</div>
</div>
</div>
</div>
)
}
}
export default PageTemplateDetails
SiteMetadata.menu запрашивается в файле шаблона сообщения:
import React from 'react'
import Helmet from 'react-helmet'
import { graphql } from 'gatsby'
import Layout from '../components/Layout'
import PostTemplateDetails from '../components/PostTemplateDetails'
class PostTemplate extends React.Component {
render() {
const { title, subtitle } = this.props.data.site.siteMetadata
const post = this.props.data.markdownRemark
const { title: postTitle, description: postDescription } = post.frontmatter
const description = postDescription !== null ? postDescription : subtitle
return (
<Layout>
<div>
<Helmet>
<title>{`${postTitle} - ${title}`}</title>
<meta name="description" content={description} />
</Helmet>
<PostTemplateDetails {...this.props} />
</div>
</Layout>
)
}
}
export default PostTemplate
export const pageQuery = graphql`
query PostBySlug($slug: String!) {
site {
siteMetadata {
title
subtitle
copyright
author {
name
twitter
}
disqusShortname
url
}
}
markdownRemark(fields: { slug: { eq: $slug } }) {
id
html
fields {
tagSlugs
}
frontmatter {
title
tags
date
description
}
}
}
`
Не уверен, что это актуально, но это файл сообщения:
import React from 'react'
import { Link } from 'gatsby'
import moment from 'moment'
import './style.scss'
class Post extends React.Component {
render() {
const {
title,
date,
category,
description,
} = this.props.data.node.frontmatter
const { slug, categorySlug } = this.props.data.node.fields
return (
<div className="post">
<div className="post__meta">
<time
className="post__meta-time"
dateTime={moment(date).format('MMMM D, YYYY')}
>
{moment(date).format('MMMM YYYY')}
</time>
<span className="post__meta-divider" />
<span className="post__meta-category" key={categorySlug}>
<Link to={categorySlug} className="post__meta-category-link">
{category}
</Link>
</span>
</div>
<h2 className="post__title">
<Link className="post__title-link" to={slug}>
{title}
</Link>
</h2>
<p className="post__description">{description}</p>
<Link className="post__readmore" to={slug}>
Read
</Link>
</div>
)
}
}
export default Post