React中存储WP REST API响应数据以实现本地过滤
嘿,这个需求太常见了!我之前用React做WP项目的时候也碰到过一模一样的场景——不想每次过滤都折腾API,毕竟第一次已经把所有数据拿回来了,直接本地处理香多了。给你一步步拆解实现方案:
核心思路:一次请求 + 本地状态存储 + 实时过滤
本质就是把首次API返回的所有文章数据存在React的状态里,之后所有的过滤操作都基于这个本地数据来做,完全不用再发起新的请求。
1. 基础单条件过滤(组件内实现)
这是最常用的场景,比如给个搜索框让用户搜文章标题/内容。直接用useState存全量数据和过滤后的数据,用useEffect监听过滤条件变化来实时筛选:
import { useState, useEffect } from 'react'; function PostFilterList() { // 存储从WP API拿到的所有文章(只存一次) const [allPosts, setAllPosts] = useState([]); // 存储当前要展示的过滤后文章 const [filteredPosts, setFilteredPosts] = useState([]); // 过滤关键词 const [searchTerm, setSearchTerm] = useState(''); const [isLoading, setIsLoading] = useState(true); // 组件挂载时只发一次请求,拿到所有文章 useEffect(() => { async function fetchAllPosts() { try { // 替换成你的WP分类文章API地址,比如/wp-json/wp/v2/posts?categories=123 const res = await fetch('你的WP REST API接口'); const posts = await res.json(); setAllPosts(posts); // 初始化时展示全部文章 setFilteredPosts(posts); setIsLoading(false); } catch (err) { console.error('获取文章失败:', err); setIsLoading(false); } } fetchAllPosts(); }, []); // 空依赖数组确保只执行一次 // 监听搜索关键词变化,实时过滤本地数据 useEffect(() => { if (!searchTerm) { // 没有关键词时展示全部 setFilteredPosts(allPosts); return; } // 按标题/内容过滤(你可以自定义规则,比如标签、日期) const result = allPosts.filter(post => { const titleMatch = post.title.rendered.toLowerCase().includes(searchTerm.toLowerCase()); const contentMatch = post.content.rendered.toLowerCase().includes(searchTerm.toLowerCase()); return titleMatch || contentMatch; }); setFilteredPosts(result); }, [searchTerm, allPosts]); // 关键词或全量数据变化时重新过滤 if (isLoading) return <div>加载中...</div>; return ( <div className="post-filter-container"> <input type="text" placeholder="搜索文章标题/内容..." value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} className="search-input" /> <div className="posts-grid"> {filteredPosts.map(post => ( <div key={post.id} className="post-card"> <h3 dangerouslySetInnerHTML={{ __html: post.title.rendered }} /> <div className="post-excerpt" dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }} /> </div> ))} </div> </div> ); } export default PostFilterList;
2. 多条件过滤进阶(比如标签/日期范围)
如果需要更复杂的过滤(比如按标签筛选、日期范围过滤),可以把过滤条件存成一个对象,然后组合多个规则筛选:
// 初始化多条件状态 const [filters, setFilters] = useState({ searchTerm: '', selectedTag: '', startDate: '' }); // 多条件过滤逻辑 useEffect(() => { let result = [...allPosts]; // 关键词过滤 if (filters.searchTerm) { result = result.filter(post => post.title.rendered.toLowerCase().includes(filters.searchTerm.toLowerCase()) ); } // 标签过滤(假设WP返回的post.tags是标签ID数组) if (filters.selectedTag) { result = result.filter(post => post.tags.includes(parseInt(filters.selectedTag)) ); } // 日期范围过滤(WP的post.date是ISO格式字符串) if (filters.startDate) { result = result.filter(post => new Date(post.date) >= new Date(filters.startDate) ); } setFilteredPosts(result); }, [filters, allPosts]); // 对应的过滤控件渲染 return ( <div> <input type="text" value={filters.searchTerm} onChange={(e) => setFilters(prev => ({...prev, searchTerm: e.target.value}))} placeholder="搜索..." /> <select value={filters.selectedTag} onChange={(e) => setFilters(prev => ({...prev, selectedTag: e.target.value}))} > <option value="">所有标签</option> {/* 这里可以渲染你的WP标签选项 */} </select> <input type="date" value={filters.startDate} onChange={(e) => setFilters(prev => ({...prev, startDate: e.target.value}))} /> {/* 文章列表 */} </div> );
3. 全局数据共享(多组件复用场景)
如果你的应用里多个组件都需要用到这些文章数据,不想每个组件都发一次请求,可以用React Context或者Redux把全量数据存在全局状态里:
用Context实现全局存储
// 创建PostsContext.js import { createContext, useContext, useState, useEffect } from 'react'; const PostsContext = createContext(); export function PostsProvider({ children }) { const [allPosts, setAllPosts] = useState([]); const [isLoading, setIsLoading] = useState(true); useEffect(() => { async function fetchPosts() { try { const res = await fetch('你的WP API地址'); const posts = await res.json(); setAllPosts(posts); setIsLoading(false); } catch (err) { console.error('获取文章失败:', err); setIsLoading(false); } } fetchPosts(); }, []); return ( <PostsContext.Provider value={{ allPosts, isLoading }}> {children} </PostsContext.Provider> ); } // 自定义Hook方便组件调用 export function usePosts() { return useContext(PostsContext); }
然后在需要的组件里直接获取全量数据:
import { usePosts } from './PostsContext'; import { useState, useEffect } from 'react'; function TagFilter() { const { allPosts, isLoading } = usePosts(); const [filteredPosts, setFilteredPosts] = useState([]); const [selectedTag, setSelectedTag] = useState(''); useEffect(() => { // 这里写过滤逻辑... }, [selectedTag, allPosts]); // 渲染内容... }
这样不管哪个组件需要过滤文章,都直接用全局的allPosts,全程只发一次API请求,效率拉满!
内容的提问来源于stack exchange,提问作者xunux
相关产品推荐
相关产品推荐

