Reactjs 按不同内容类型的日期排序内容丰富的帖子

Reactjs 按不同内容类型的日期排序内容丰富的帖子,reactjs,graphql,gatsby,contentful,static-site,Reactjs,Graphql,Gatsby,Contentful,Static Site,这是我第一个使用GatsbyJS和Contentful的项目。现在我在网站上有几篇文章,内容模式不同。为了简单起见,假设我有一些内容类型是照片,其他是视频嵌入。我正在使用GraphQL获取帖子 每种类型我都有不同的组件 照片(也称为照片部分) 视频嵌入(也称为电影部分) 然后,我将所有组件编译到另一个名为Blog的组件中 const Blog = () => { return ( <div> <AudioSection /> &l

这是我第一个使用GatsbyJS和Contentful的项目。现在我在网站上有几篇文章,内容模式不同。为了简单起见,假设我有一些内容类型是照片,其他是视频嵌入。我正在使用GraphQL获取帖子

每种类型我都有不同的组件

照片(也称为照片部分)

视频嵌入(也称为电影部分)

然后,我将所有组件编译到另一个名为Blog的组件中

const Blog = () => {
  return (
    <div>
      <AudioSection />
      <FilmSection />
      <PhotoSection />
    </div>
  )
}

export default Blog
constblog=()=>{
返回(
)
}
导出默认博客
最终的结果是,帖子按日期降序排列,但也按其章节/内容类型进行组织。如果遵循代码块,顺序是AudioSection->FilmSection->PhotoSection。我希望他们被订购的日期(最新的第一),无论内容类型

希望这是有道理的。真的不知道该怎么办

先谢谢你

编辑…这是一篇尝试建议内容的文章。我删掉了一些笨重的部分,但留下了光组件作为例子

constblogtow2=()=>{
常量数据=useStaticQuery(graphql`
质疑{
音乐:{bla bla}
视频:{bla bla}
图像:allContentfulImage(排序:{字段:日期,顺序:DESC}){
节点{
类型:\类型名称
形象{
描述
文件{
网址
}
}
}
}
`)
const dataForDisplay=[data.music,data.images,data.videos].sort(
(a,b)=>b.date-a.date
)
常量组件类型映射={
内容丰富的音乐艺术:音乐成分,
ContentfulImage:光组件,
ContentfulVideoEmbeddes:FilmComponent,
}
常量MusicComponent=()=>{
返回(
呜呜呜呜
)
}
常数光电元件=()=>{
返回(
)
}
常数FilmComponent=()=>{
返回(
呜呜呜呜
)
}
返回(
{dataForDisplay.map({type,props})=>
React.createElement(componentTypeMap[type],props)
)}
)
}
导出默认BlogTwo

不要将每个内容类型包装在一个
whateverssection
组件中,而是将所有三个内容数组组合成一个数组,对其排序,然后在组合数组中循环,为每个条目呈现相关组件

为了使这更合理,我将重构静态查询的使用,将它们提升到blog组件中,组合它们,并添加GraphQL别名以减少检索数据的冗长

const Blog = () => {
  const data = useStaticQuery(graphql`
    query {
      images: allContentfulImage(sort: { fields: date, order: DESC }) {
        nodes {
          type: __typename
          date
          image {
            description
            file {
              url
            }
          }
        }
      }

      videos: allContentfulVideoEmbeds(sort: { fields: date, order: DESC }) {
        nodes {
          type: __typename
          date
          embedURL
        }
      }
    }
  `)

  const dataForDisplay = [...data.images.nodes, ...data.videos.nodes].sort((a, b) => b.date - a.date)

  return (
    <div>
      {dataForDisplay.map(({ type, ...props }) => 
        React.createElement(componentTypeMap[type], props)
      )}
    </div>
  )
}

export default Blog

const componentTypeMap = {
  ContentfulImage: PhotoComponent,
  ContentfulVideoEmbed: FilmComponent,
}
constblog=()=>{
常量数据=useStaticQuery(graphql`
质疑{
图像:allContentfulImage(排序:{字段:日期,顺序:DESC}){
节点{
类型:\类型名称
日期
形象{
描述
文件{
网址
}
}
}
}
视频:AllContentfulVideoEmbeddes(排序:{字段:日期,顺序:DESC}){
节点{
类型:\类型名称
日期
嵌入URL
}
}
}
`)
const dataForDisplay=[…data.images.nodes,…data.videos.nodes].sort((a,b)=>b.date-a.date)
返回(
{dataForDisplay.map({type,…props})=>
React.createElement(componentTypeMap[type],props)
)}
)
}
导出默认博客
常量组件类型映射={
ContentfulImage:光组件,
ContentfulVideoEmbed:FilmComponent,
}

非常感谢,我想我就快到了。但是,我从控制台收到一个错误,说->错误:元素类型无效:需要字符串(对于内置组件)或类/函数(对于复合组件)但是得到:未定义。您可能忘记了从定义组件的文件中导出组件,或者您可能混淆了默认导入和命名导入。有什么想法吗?您的数组中可能有一个组件类型不在
componentTypeMap
中。通常,如果是这种情况,我会进行快速检查并在控制台上记录警告,以便在开发中看到它,但在生产中不要破坏页面。我编辑了我的初始帖子以显示我添加的内容(删去大部分内容,但留下照片组件作为示例).我认为阵列的实现是正确的b/c我检查了控制台,它显示组件都是正确的there@AaronLyons我认为问题在于,在创建合并类型数组(
dataForDisplay
)时,我忘记了展开
节点。我已经更新了我的代码以反映这一点。哈哈哈哇,我没意识到你希望我在数组中实际包含省略号。我以为这只是你的表达方式,等等。刚刚了解了扩展运算符是什么。谢谢一群家伙:)
const Blog = () => {
  return (
    <div>
      <AudioSection />
      <FilmSection />
      <PhotoSection />
    </div>
  )
}

export default Blog
const BlogTwo = () => {
  const data = useStaticQuery(graphql`
    query {
      music: { bla bla bla }
      videos: { bla bla bla }
      images: allContentfulImage(sort: { fields: date, order: DESC }) {
        nodes {
          type: __typename
          image {
            description
            file {
              url
            }
          }
        }
      }
  `)

  const dataForDisplay = [data.music, data.images, data.videos].sort(
    (a, b) => b.date - a.date
  )

  const componentTypeMap = {
    ContentfulMusicAndArt: MusicComponent,
    ContentfulImage: PhotoComponent,
    ContentfulVideoEmbeds: FilmComponent,
  }

  const MusicComponent = () => {
    return (
      <div>
        bla bla bla
      </div>
    )
  }

  const PhotoComponent = () => {
    return (
      <div className={`${blogStyles.blogDiv}`}>
        <div className={`${blogStyles.blogPost} ${blogStyles.image}`}>
          <img
            src={data.images.nodes.image.file.url}
            alt={data.images.nodes.image.description}
          />
        </div>
      </div>
    )
  }

  const FilmComponent = () => {
    return (
      <div>
        bla bla bla
      </div>
    )
  }

  return (
    <div>
      {dataForDisplay.map(({ type, props }) =>
        React.createElement(componentTypeMap[type], props)
      )}
    </div>
  )
}
export default BlogTwo

const Blog = () => {
  const data = useStaticQuery(graphql`
    query {
      images: allContentfulImage(sort: { fields: date, order: DESC }) {
        nodes {
          type: __typename
          date
          image {
            description
            file {
              url
            }
          }
        }
      }

      videos: allContentfulVideoEmbeds(sort: { fields: date, order: DESC }) {
        nodes {
          type: __typename
          date
          embedURL
        }
      }
    }
  `)

  const dataForDisplay = [...data.images.nodes, ...data.videos.nodes].sort((a, b) => b.date - a.date)

  return (
    <div>
      {dataForDisplay.map(({ type, ...props }) => 
        React.createElement(componentTypeMap[type], props)
      )}
    </div>
  )
}

export default Blog

const componentTypeMap = {
  ContentfulImage: PhotoComponent,
  ContentfulVideoEmbed: FilmComponent,
}