这个问题背后有很多信息。我会尽力在这里展示一切。
我正在使用 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 从一篇博文传递到另一篇博文,并使用超链接将用户发送到外部网站。
你能帮我吗?
答案很简单。正如您所看到的,您检查链接的方式与检查粗体或斜体的方式相同,但如果您密切注意,您的链接标识符位于顶层和/或包含在类型键中。
因此,您应该期望的第一件事是将类型匹配为链接,因此您应该检查:
,而不是
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
的兄弟姐妹