You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:50:30