Как я могу реализовать гиперссылку в этом коде?
За этой проблемой стоит много информации. Я постараюсь здесь все показать.
Я использую 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;
};
Мне нужно было создать способ рендеринга всех узлов, которые предоставляет гиграф при создании текста. В качестве примера я использовал контент, который я видел в этом видео (здесь) на 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, чтобы увидеть, что связано со «ссылкой», и там тоже есть свойства: nodeId и Href.
Содержимое с гиперссылкой не отображается, и я не знаю, что делаю неправильно. Я хочу использовать nodeId для перехода от одного сообщения блога к другому и использовать гиперссылку для отправки пользователя на внешний веб-сайт.
Вы можете помочь мне?
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