如何在此代码上实现超链接?

问题描述 投票:0回答:1

这个问题背后有很多信息。我会尽力在这里展示一切。

我正在使用 Hygraph 和 GraphQL 创建一个带有 Headless CMS 的博客,并且在我的 API 调用中我有 getPostDetails。这是有效的,我的问题与内容 { raw } 有关。

    export const getPostDetails = async (slug) => {
      const query = gql`
        query GetPostDetails($slug: String!) {
          post(where: {slug: $slug}) {
            title
            excerpt
            featuredImage {
              url
            }
            author{
              name
              bio
              photo {
                url
              }
            }
            createdAt
            slug
            content {
              raw 
            }
            categories {
              name
              slug
            }
          }
        }
      `;
    
      const result = await request(graphqlAPI, query, { slug });
    
      return result.post;
    };

我需要创建一种方法来渲染创建文本时 hygraph 提供的所有节点。因此,以我在 2:01:36 在此视频(此处)中看到的内容为例,文章详细信息。

'use client'

import React, { useEffect, useState } from 'react';
import { getPostDetails } from '@/app/api';
import { Flex, Grid, GridItem, Heading, Image, Link, Text } from '@chakra-ui/react';
import AdAside from '../../UI/Atoms/AdAside';

export default function PostPage({ params: { slug }}) {
  const getContentFragment = (index, text, obj, type) => {
    let modifiedText = text;

    if (obj) {
      if (obj.bold) {
        modifiedText = (<b key={index}>{text}</b>);
      }

      if (obj.italic) {
        modifiedText = (<em key={index}>{text}</em>);
      }

      if (obj.underline) {
        modifiedText = (<u key={index}>{text}</u>);
      }

      if (obj.link) {
        modifiedText = (<a key={index} href={obj.nodeId}>{text}</a>);
      }
      
    }

    switch (type) {
      case 'heading-three':
        return <Heading as='h3' key={index}>{modifiedText.map((item, i) => <React.Fragment key={i}>{item}</React.Fragment>)}</Heading>;
      case 'paragraph':
        return <Text key={index} maxWidth="1200px" mb={8}>{modifiedText.map((item, i) => <React.Fragment key={i}>{item}</React.Fragment>)}</Text>;
      case 'heading-four':
        return <Heading as='h4' key={index}>{modifiedText.map((item, i) => <React.Fragment key={i}>{item}</React.Fragment>)}</Heading>;
      case 'image':
        return (
          <Image
            key={index}
            alt={obj.title}
            height={obj.height}
            width={obj.width}
            src={obj.src}
          />
        );
      case 'link':
      return <Link key={index} href={obj.nodeId}>{modifiedText.map((item, i) => <React.Fragment key={i}>{item}</React.Fragment>)}</Link>

      default:
        return modifiedText;
    }
  };

  const [pagePost, setPagePost] = useState(null);

  useEffect(() => {
    const fetchPost = async () => {
      try {
        if (slug) {
          const result = await getPostDetails(slug);
          setPagePost(result);
        }
      } catch (error) {
        console.error(error);
      }
    };

    fetchPost();
    console.log(pagePost)
  }, [slug]);

  if (!pagePost) {
    return <div>Loading...</div>;
  }
  
  return (
    <>
    <Image
      w="100vw" 
      maxHeight='600px' 
      objectFit='cover' 
      alt='banner content' 
      src={pagePost.featuredImage.url}
      />
    <Grid 
    templateColumns="repeat(12, 1fr)" 
    gap={1} 
    px={6} 
    py={10}
    >
      <GridItem 
      gridColumn={{ base: 'span 12', lg: 'span 8' }}
      >
      <Flex 
      maxWidth="1200px" 
      flexDirection="column"
       >
        <Heading textAlign='left' mb={16}>
          {pagePost.title}
          </Heading>
        <Flex 
        textAlign="left" 
        flexDirection="column"
        >
        {pagePost.content.raw.children.map((typeObj, index) => {
          const children = typeObj.children.map((item, itemindex) => getContentFragment(itemindex, item.text, item));
          
          return getContentFragment(index, children, typeObj, typeObj.type);
        })}
        </Flex>

      </Flex>
      </GridItem>
      <GridItem gridColumn={{ base: 'span 12', lg: 'span 4' }}>
        <AdAside />
      </GridItem>
    </Grid>
      
    </>
  );
}

如果您观看视频,您就会看到

      if (obj.link) {
        modifiedText = (<a key={index} href={obj.nodeId}>{text}</a>);
      }

case 'link':
      return <Link key={index} href={obj.nodeId}>{modifiedText.map((item, i) => <React.Fragment key={i}>{item}</React.Fragment>)}</Link>

那里不存在。我包括尝试找到一种使用超链接的方法。此外,我在 Hygraph Playground 中查看了与“link”相关的内容,并且还有属性:nodeId 和 Href。

带有超链接的内容没有被渲染,我不知道我做错了什么。我想使用 nodeId 从一篇博文传递到另一篇博文,并使用超链接将用户发送到外部网站。

你能帮我吗?

next.js graphql blogs headless-cms hygraph
1个回答
1
投票

答案很简单。正如您所看到的,您检查链接的方式与检查粗体或斜体的方式相同,但如果您密切注意,您的链接标识符位于顶层和/或包含在类型键中。

因此,您应该期望的第一件事是将类型匹配为链接,因此您应该检查:

,而不是 
obj.link

if(obj.type === 'link') {
  modifiedText = (<a key={index} href={obj.href}>
    {getContentFragment(0, obj.children[0].text, obj.children, obj.children.props)}
  </a>)
}

您会看到内部发生引用,因为当您有

type === "link"
时,您的文本应该位于子级内部,而不是作为
obj.type

的兄弟姐妹
© www.soinside.com 2019 - 2024. All rights reserved.