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

wj8zmpe1  于 2023-08-04  发布在  其他
关注(0)|答案(1)|浏览(132)

这个问题背后有很多信息。我会试着在这里展示一切。
我正在使用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在此视频(here)上看到的内容为例,文章详细信息。

'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。
x1c 0d1x的数据
超链接的内容没有被渲染,我不知道我做错了什么。我想使用nodeId从一个博客文章传递到另一个博客文章,并使用超链接将用户发送到外部网站。
你能帮我吗?

omvjsjqw

omvjsjqw1#

答案很简单。如您所见,您检查链接的方式与检查粗体或斜体的方式相同,但如果您密切注意,您的链接标识符将位于顶级和/或包含在类型键中。
因此,您首先应该看到得是将类型匹配为link,因此您应该检查得不是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的同级

相关问题