По какой-то причине, когда я нажимаю на одно из сообщений в разделе коллекции сообщений, чтобы просмотреть информацию об одном отдельном сообщении, мой код не добавляет косую черту /
в URL-адрес, например: http://localhost:3000/postyou-just-could-not-have
где URL-адрес, который мне нужен, http://localhost:3000/post/you-just-could-not-have
.
Есть ли способ добавить /
к URL-адресу или выяснить, почему он не генерируется?
App.js с маршрутом <Route path = "/post/:slug" element = {<SinglePost />} />
в вопросе:
import React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import Home from './components/Home';
import About from './components/About';
import SinglePost from './components/SinglePost';
import Post from './components/Post';
import Project from './components/Project';
import NavBar from './components/NavBar';
function App() {
return (
<Router>
<NavBar />
<Routes>
<Route path = "/" element = {<Home />} exact />
<Route path = "/about" element = {<About />} />
<Route path = "/post/:slug" element = {<SinglePost />} />
<Route path = "/post" element = {<Post />} />
<Route path = "/project" element = {<Project />} />
</Routes>
</Router>
);
}
export default App;
Компонент SinglePost.js пытается создать URL-адрес из значения slug:
import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import sanityClient from '../client';
import BlockContent from '@sanity/block-content-to-react';
import imageUrlBuilder from '@sanity/image-url';
const builder = imageUrlBuilder(sanityClient);
function urlFor(source) {
return builder.image(source);
}
export default function SinglePage() {
const [singlePost, setSinglePost] = useState(null);
const { slug } = useParams();
useEffect(() => {
sanityClient
.fetch(
`*[slug.current == "${slug}"]{
title,
_id,
slug,
mainImage{
asset->{
_id,
url
}
},
body,
"name": author->name,
"authorImage": author->image
}`
)
.then((data) => setSinglePost(data[0]))
.catch(console.error);
}, [slug]);
if (!singlePost) {
return <div>Loading...</div>;
}
return (
<main className = "bg-gray-200 min-h-screen p-12">
<article className = "container shadow-lg mx-auto bg-green-100 rounded-lg">
<header className = "relative">
<div className = "absolute h-full w-full flex items-center justify-center p-8">
<div className = "bg-white bg-opacity-75 rounded p-12">
<h1 className = "cursive text-3xl lg:text-6xl mb-4">
{singlePost.title}
</h1>
<div className = "flex justify-center text-gray-800">
<img
src = {urlFor(singlePost.authorImage).url()}
alt = "bob"
className = "w-10 h-10 rouded-full"
/>
<p className = "cursive flex items-center pl-2 text-2xl">
{singlePost.name}
</p>
</div>
</div>
</div>
<img
src = {singlePost.mainImage.asset.url}
alt = "gary"
className = "w-full object-cover rounded-t"
style = {{ height: '400px' }}
/>
</header>
<div className = "px-16 lg:px-48 py-12 lg:py-20 prose lg:prose-xl max-w-full">
<BlockContent
blocks = {singlePost.body}
projectId = "notReally"
dataset = "production"
/>
</div>
</article>
</main>
);
}
Adding Post.js :
import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import sanityClient from '../client';
export default function Post() {
const [postData, setPost] = useState(null);
useEffect(() => {
sanityClient
.fetch(
`*[_type == "post"]{
title,
slug,
mainImage{
asset->{
_id,
url
},
alt
}
}`
)
.then((data) => setPost(data))
.catch(console.error);
}, []);
//anything wrapped in Link makes it clickable
return (
<main className = "bg-green-100 min-h-screen p-12">
<section className = "container mx-auto">
<h1 className = "text-5xl flex justify-center cursive">Blog Post Page</h1>
<h2 className = "text-lg text=gray-600 flex justify-center mb-12">
Welcome Doggies
</h2>
<div className = "grid md:grid-cols-2 lg:grid-cols-3 gap-8">
{postData &&
postData.map((post, index) => (
<article>
<Link to = {'/post' + post.slug.current} key = {post.slug.current}>
<span
className = "block h-64 relative rounded shadow leading-snug bg-white border-l-8 border-green-400"
key = {index}
>
<img
src = {post.mainImage.asset.url}
alt = "photo"
className = "w-full h-full rounded-r object-cover absolute"
/>
<span className = "block relative h-full flex justify-end items-end pr-4 pb-4">
<h3 className = "text-gray-800 text-lg font-blog px-3 py-4 bg-red-700 text-red-100 bg-opacity-75 rounded">
{post.title}
</h3>
</span>
</span>
</Link>
</article>
))}
</div>
</section>
</main>
);
}
Есть ли шанс показать нам <Post />
или, по крайней мере, как реализована навигация к <SinglePost />
?
@JohnLi Спасибо. К этому вопросу добавлен Post.js.
Ссылки по умолчанию относятся к иерархии маршрутов, если только не задано значение, начинающееся с /
.
В <Post />
попробуйте один из следующих способов:
<Link to = {post.slug.current} key = {post.slug.current}>
...
/Link>
Или:
<Link to = {'/post/' + post.slug.current} key = {post.slug.current}>
...
/Link>
Мы надеемся, что они сгенерируют правильный путь как /post/:slug
.
Успешно справился! Спасибо, нашел свою опечатку без добавления завершающего /.
Я не вижу код, который генерирует этот URL