使用 onChange 从 <select> 标签更新状态并过滤类别列表以显示该类别的博文

Update state from <select> tag using onChange and filter through list of categories to display blog posts from that category

我通过将这些类别的名称存储在数组中的字符串中来动态呈现类别下拉列表,并希望根据下拉列表中 selected 的类别更新我的博客文章列表.

类别数组如下所示:

const tags = ['Sustainability', 'Electrical', 'Mechanical', 'Engineering']

然后我通过这个数组映射以在 select 标签下拉列表中显示这些字符串,如下所示:

 <div className='col-span-8 md:col-span-2'>
            <select
              placeholder='Categories'
              onChange={handleChange}>
              <option value='' selected disabled hidden>
                Choose Category
              </option>
              {tags.map((t) => (
                <option>{t}</option>
              ))}
            </select>
          </div>

然后我有一个来自 Prismic(无头 CMS)的博客列表,我已将其存储在状态中,并且正在映射以在 UI 中列出它们。我将它们存储在名为 selectedBlogs 的状态中,如下所示:

  const [selectedBlogs, setSelectedBlogs] = useState(blogs);

并像这样映射(这只显示当前的每个博客)

{selectedBlogs.results.map((blog) => (
            <SwiperSlide key={blog.data.title} className='blog-wrap1'>
              <a
                href={`/resource/${blog.slugs}`}
                className='h-full object-cover'>
                <img src={blog.data.image.url} alt='' />
                <div className='absolute bottom-5 text-left text-white p-5 w-full font-header'>
                  <h1 className='text-2xl overflow-ellipsis'>
                    {RichText.asText(blog.data.title)}
                  </h1>
                </div>{' '}
              </a>
            </SwiperSlide>
          ))}

简而言之,我想根据此下拉列表中selected 的类别更新此博客列表,并在 selected 时过滤博客并仅显示该类别中的博客类别。

我知道我需要在我拥有的 select 标记中使用 onChange,但是我如何存储 selected 的下拉项并根据它重新呈现我的博文?

非常感谢您的指导!

我假设这就是您设置 handleChange 函数的方式,然后执行以下步骤:

const tags = ['Sustainability', 'Electrical', 'Mechanical', 'Engineering']
const [selectedBlogs, setSelectedBlogs] = useState(blogs);

/* you need this below state to store selected tag */
const [selectedTag, setSelectedTag] = useState("")   

/* handle the value selected from the form option */  
const handleChange = (e) => {
    const selected_tag = e.target.value;
    setSelectedTag(selected_tag)
}

useEffect(() => {
   const filtered_blog = blogs.filter(blog => blog.data.tag === selectedTag);
   setSelectedBlogs(filtered_blog)
}, [selectedTag]) // <--- listen to the changes on selectedTag that trigger this 
// Then your selectedBlogs will update everytime you change the tag

我会引入一个新的状态来设置过滤器:

const [filter, setFilter] = useState('')

然后在 select 元素上使用 onClick() 处理程序设置状态。

因为这不是我们可以跟踪每个字母变化的输入字段,所以我不会使用 onChange。

<option onClick={()=>setFilter(t)}></option>

您应该能够将该状态传递给过滤函数: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/filter

为了确保过滤器函数在我们的过滤器状态发生变化时运行,我将其包装在 useEffect-hook 中:

useEffect 钩子在最后进入一个状态。每当该状态更新时,钩子内的函数就会运行一次。每当您通过单击标签更新 'filter' 状态时,我就是您的情况。

useEffect(()=>{
 
 console.log(your-filterfunction)

},[filter])