首页 > 解决方案 > 如何使用 React/GatsbyJS 将 Contentful 数据随机呈现到 div onClick

问题描述

盖茨比/反应菜鸟在这里。

我在 Contentful 中创建了一个名为 Topic 的内容类型。每个主题都包含一个标题、描述和主题页面的 slug。目前,我能够将每个主题呈现为页面上的卡片。我现在想弄清楚的是如何一次只渲染一张卡片,并在单击旋转按钮时随机更改卡片内容(标题/说明)。

我创建了这个快速演示,以直观地展示我的目标。

这是我渲染每个主题卡的地方:

import React from 'react'
import { graphql, navigate, StaticQuery } from 'gatsby'
import './topicFeed.scss'

export default () => (
   <StaticQuery
     query={graphql` 
     query TopicFeed {
  allContentfulTopic(filter: {featured: {eq: true}}) {
    edges {
      node {
        cardDescription {
          cardDescription
        }
        cardTitle
        id
        slug
      }
    }
  }
}
`}   
     render={data => ( 
      
          <div>
            <div className='feed'>
                {data.allContentfulTopic.edges.map(edge => (
                <div key={edge.node.id} className='topic__item'>
                    <h2 className='card__title'>{edge.node.cardTitle}</h2>
                    <div className="card__desc--container">
                        <p className='card__desc'>{edge.node.cardDescription.cardDescription}</p>
                    </div>
                    <div className='card__link' onClick={() => navigate(`/topic/${edge.node.slug}`)}>
                        <p>Learn More</p>
                    </div>
                </div>
                ))}
            </div>

            <button onClick={() =>console.log('werked')}onClick={() =>console.log('werked')}>SPIN</button>
        </div>
     )}
   />
 )

我的理解是 gatsby 在构建时为每张卡片呈现 div,所以我对用户如何在点击时操作这些数据感到困惑。

标签: reactjsgatsbycontentfulheadless-cmsjamstack

解决方案


尝试这样的事情。与其映射整个卡片数组,不如只显示一个索引。单击按钮时,设置随机卡片索引。

import React, { useState } from 'react'
import { graphql, navigate, StaticQuery } from 'gatsby'
import './topicFeed.scss'

export default () => {
  const [cardIndex, setCardIndex] = useState(0)

  const getRandomCardIndexBetween = (min, max) => Math.floor(Math.random() * (Math.floor(max) - Math.ceil(min) + 1)) + min

  return (
    <StaticQuery
      query={graphql` 
          query TopicFeed {
              allContentfulTopic(filter: {featured: {eq: true}}) {
                  edges {
                      node {
                          cardDescription {
                              cardDescription
                          }
                          cardTitle
                          id
                          slug
                      }
                  }
              }
          }
      `}
      render={data => {
        const {
          cardDescription: {
            cardDescription
          },
          cardTitle,
          slug,
        } = data.allContentfulTopic.edges[cardIndex].node;

        return (
          <div>
            <div className='feed'>
              <div className='topic__item'>
                <h2 className='card__title'>{cardTitle}</h2>
                <div className="card__desc--container">
                  <p className='card__desc'>{cardDescription}</p>
                </div>
                <div className='card__link' onClick={() => navigate(`/topic/${slug}`)}>
                  <p>Learn More</p>
                </div>
              </div>
            </div>

            <button onClick={setCardIndex(getRandomCardIndexBetween(0, data.allContentfulTopic.edges.length - 1))}>SPIN</button>
          </div>
        )}}
    />
  )
}

这是一个jsfiddle,展示了如何使用普通的 React(没有 Gatsby/GraphQL)来实现这一点


推荐阅读