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