[英]React button not rerendering the component
I am making a blog with React and Sanity, and am trying to use buttons to allow the user to sort blog posts by tag (category).我正在使用 React 和 Sanity 制作博客,并尝试使用按钮允许用户按标签(类别)对博客文章进行排序。 Currently, the sorting works fine if I hard code the tag I want to sort the posts by, but I want to be able to use buttons to change the sort tag.目前,如果我对要对帖子进行排序的标签进行硬编码,排序工作正常,但我希望能够使用按钮来更改排序标签。 Right now the button is able to change text on the screen to the correct category, but It does not update the visible posts (does not actually sort them).现在该按钮能够将屏幕上的文本更改为正确的类别,但它不会更新可见的帖子(实际上不会对它们进行排序)。
Here is my code for the blog page:这是我的博客页面代码:
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;
As I said, this code works perfectly fine other than actually rerendering the correct posts when a button is clicked to sort by a specific tag.正如我所说,除了在单击按钮以按特定标签排序时实际重新呈现正确的帖子之外,此代码工作得非常好。 Any help is appreciated!任何帮助表示赞赏!
If you fetch data and setPosts
in useEffect
, You should add sort
state to useEffect
dependency, to update the posts when you change the sort
state value by setSort
.如果您在useEffect
中获取数据和setPosts
,则应将sort
state 添加到useEffect
依赖项,以便在您通过setSort
更改sort
state 值时更新帖子。 like below:如下所示:
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])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.