React 按钮不重新渲染组件
React button not rerendering the component
我正在使用 React 和 Sanity 制作博客,并尝试使用按钮允许用户按标签(类别)对博客文章进行排序。目前,如果我对要对帖子进行排序的标签进行硬编码,则排序工作正常,但我希望能够使用按钮来更改排序标签。现在该按钮能够将屏幕上的文本更改为正确的类别,但它不会更新可见的帖子(实际上不会对它们进行排序)。
这是我的博客页面代码:
import React from "react";
import { useState, useEffect } from "react"
import Footer from "../Footer";
import Header from "./Header";
import client from "../../client"
import BlockContent from "@sanity/block-content-to-react";
import { Link } from "react-router-dom";
const Blog = () =>
{
const [posts, setPosts] = useState([])
const [sort, setSort] = useState("all")
useEffect(() => {
client.fetch(
//This line sorts posts by the value of 'keyword'
`*[_type == "post" && $keyword in tags] {
title,
slug,
body,
mainImage {
asset -> {
_id,
url
},
alt
},
tags,
publishedAt
}`,{"keyword":sort} //This line sets the value of 'keyword' to the value of 'sort'
)
.then((data) => setPosts(data))
.catch(console.error)
}, [])
//This function prints the tag that was clicked to the console and updates the
//value of 'sort'. It is supposed to rerender the component to display only the
//posts associated with the tag clicked, but it does not.
function sortPosts(e) {
console.log(e)
setSort(e)
}
return (
<div className = "bg-gray-100 dark:bg-zinc-900">
<Header />
<div className = "" >
<p className = "title pt-32">Welcome to My Blog!</p>
//This line correctly displays the tag that is supposed to determine which posts to display
<p className = "text-center font-semibold">Currently showing: {sort} posts</p>
<div className = "flex items-center justify-center mt-16">
<div className = "grid grid-cols-1 xl:grid-cols-3 lg:grid-cols-2 md:grid-cols-1 gap-10 mx-16">
{posts.map((post) => (
<article key={post.slug.current} className = "rounded-xl max-w-sm bg-white dark:bg-zinc-950 shadow-xl dark:shadow-gray-100/10">
<img src={post.mainImage.asset.url} alt={post.title} className = "object-fill object-center rounded-t-xl" />
<div className = "p-6">
<p className = "text-2xl font-semibold mb-3 dark:text-gray-100">{post.title}</p>
{post.tags.map((tags, key) => (
<div className = "inline-block">
//This line displays a button for each tag associated with the current post and calls the sortPosts function
<button key = {key} onClick={() => sortPosts(tags)} className = "px-2 inline-flex mb-2 mr-2 rounded-2xl hover:bg-white bg-gray-100 dark:hover:bg-zinc-950 dark:bg-zinc-800 dark:text-white duration-300 transition-colors cursor-pointer">{tags}</button>
</div>
))}
<div class = "preview">
<BlockContent blocks={post.body} projectId="2hp9gld0" dataset="production" />
</div>
<button className="button-main items-center mt-2 dark:text-gray-100 block">
<Link to = {`/blog/${post.slug.current}`} className = "">Read Full Article</Link>
</button>
</div>
</article>
))}
</div>
</div>
</div>
<div className = "pb-10 bg-gray-100 dark:bg-zinc-900">
<Footer />
</div>
</div>
)
}
export default Blog;
正如我所说,除了在单击按钮按特定标签排序时实际重新呈现正确的帖子之外,这段代码工作得非常好。感谢您的帮助!
如果您在 useEffect
中获取数据和 setPosts
,您应该将 sort
状态添加到 useEffect
依赖项,以便在您更改 [=13] 时更新帖子=] 状态值 setSort
。
如下所示:
const [posts, setPosts] = useState([])
const [sort, setSort] = useState("all")
useEffect(() => {
client.fetch(
//This line sorts posts by the value of 'keyword'
...
.then((data) => setPosts(data))
.catch(console.error)
}, [sort])
我正在使用 React 和 Sanity 制作博客,并尝试使用按钮允许用户按标签(类别)对博客文章进行排序。目前,如果我对要对帖子进行排序的标签进行硬编码,则排序工作正常,但我希望能够使用按钮来更改排序标签。现在该按钮能够将屏幕上的文本更改为正确的类别,但它不会更新可见的帖子(实际上不会对它们进行排序)。
这是我的博客页面代码:
import React from "react";
import { useState, useEffect } from "react"
import Footer from "../Footer";
import Header from "./Header";
import client from "../../client"
import BlockContent from "@sanity/block-content-to-react";
import { Link } from "react-router-dom";
const Blog = () =>
{
const [posts, setPosts] = useState([])
const [sort, setSort] = useState("all")
useEffect(() => {
client.fetch(
//This line sorts posts by the value of 'keyword'
`*[_type == "post" && $keyword in tags] {
title,
slug,
body,
mainImage {
asset -> {
_id,
url
},
alt
},
tags,
publishedAt
}`,{"keyword":sort} //This line sets the value of 'keyword' to the value of 'sort'
)
.then((data) => setPosts(data))
.catch(console.error)
}, [])
//This function prints the tag that was clicked to the console and updates the
//value of 'sort'. It is supposed to rerender the component to display only the
//posts associated with the tag clicked, but it does not.
function sortPosts(e) {
console.log(e)
setSort(e)
}
return (
<div className = "bg-gray-100 dark:bg-zinc-900">
<Header />
<div className = "" >
<p className = "title pt-32">Welcome to My Blog!</p>
//This line correctly displays the tag that is supposed to determine which posts to display
<p className = "text-center font-semibold">Currently showing: {sort} posts</p>
<div className = "flex items-center justify-center mt-16">
<div className = "grid grid-cols-1 xl:grid-cols-3 lg:grid-cols-2 md:grid-cols-1 gap-10 mx-16">
{posts.map((post) => (
<article key={post.slug.current} className = "rounded-xl max-w-sm bg-white dark:bg-zinc-950 shadow-xl dark:shadow-gray-100/10">
<img src={post.mainImage.asset.url} alt={post.title} className = "object-fill object-center rounded-t-xl" />
<div className = "p-6">
<p className = "text-2xl font-semibold mb-3 dark:text-gray-100">{post.title}</p>
{post.tags.map((tags, key) => (
<div className = "inline-block">
//This line displays a button for each tag associated with the current post and calls the sortPosts function
<button key = {key} onClick={() => sortPosts(tags)} className = "px-2 inline-flex mb-2 mr-2 rounded-2xl hover:bg-white bg-gray-100 dark:hover:bg-zinc-950 dark:bg-zinc-800 dark:text-white duration-300 transition-colors cursor-pointer">{tags}</button>
</div>
))}
<div class = "preview">
<BlockContent blocks={post.body} projectId="2hp9gld0" dataset="production" />
</div>
<button className="button-main items-center mt-2 dark:text-gray-100 block">
<Link to = {`/blog/${post.slug.current}`} className = "">Read Full Article</Link>
</button>
</div>
</article>
))}
</div>
</div>
</div>
<div className = "pb-10 bg-gray-100 dark:bg-zinc-900">
<Footer />
</div>
</div>
)
}
export default Blog;
正如我所说,除了在单击按钮按特定标签排序时实际重新呈现正确的帖子之外,这段代码工作得非常好。感谢您的帮助!
如果您在 useEffect
中获取数据和 setPosts
,您应该将 sort
状态添加到 useEffect
依赖项,以便在您更改 [=13] 时更新帖子=] 状态值 setSort
。
如下所示:
const [posts, setPosts] = useState([])
const [sort, setSort] = useState("all")
useEffect(() => {
client.fetch(
//This line sorts posts by the value of 'keyword'
...
.then((data) => setPosts(data))
.catch(console.error)
}, [sort])