初学React:请求数据参数未更新 && 数据异步状态更新问题

javascript 复制代码
 // 请求参数
const [params, setParams] = useState({
    page: 1,
    per_page: 4,
    begin_pubdate: null,
    end_pubdate: null,
    status: '',
    channel_id: null
  })
  // 点击按钮
 const onFinish = (formValue)=>{
    // 设置参数
    setParams({
      ...params,
      channel_id:formValue.channel_id,
      status: formValue.status,
      begin_pubdate: formValue.date ? formValue.date[0].format('YYYY-MM-DD') : null,
      end_pubdate:  formValue.date ? formValue.date[1].format('YYYY-MM-DD')  :  null
    })
  // 更新表格数据
    getTableList()
  }

首次点击按钮导致请求参数没有更新问题。

原因在于 React 的状态更新是异步的。在 onFinish 函数中,先调用了 setParams 更新筛选参数,然后立即调用 getTableList。但由于 setParams 不会立即修改 params 的值,此时 getTableList 内部读取的仍然是旧的 params,因此第一次请求没有带上新选择的筛选条件。第二次点击时,params 已经更新为上一次的值,所以请求能带上上次的条件,但这次又可能因为同样的原因滞后。

解决方案

1. 在 onFinish 中构造新参数并直接传给 getTableList(推荐)

修改 getTableList 使其接受参数,调用时传入最新的筛选条件。

javascript 复制代码
// 修改 getTableList,增加参数
const getTableList = async (reqParams) => {
  // 如果没有传入参数,则使用当前 state 中的 params(用于首次加载)
  const finalParams = reqParams || params;
  try {
    const res = await http.get('/mp/articles', { params: finalParams });
    const { results, total_count } = res.data;
    setArticleTableList({
      list: results,
      count: total_count
    });
  } catch (error) {
    console.log(error);
  }
};

// 修改 onFinish
const onFinish = (formValue) => {
  // 基于当前 params 和表单值构造新参数对象
  const newParams = {
    ...params,
    channel_id: formValue.channel_id,
    status: formValue.status,
    begin_pubdate: formValue.date ? formValue.date[0].format('YYYY-MM-DD') : null,
    end_pubdate: formValue.date ? formValue.date[1].format('YYYY-MM-DD') : null
  };
  setParams(newParams);          // 更新状态用于后续操作(如分页)
  getTableList(newParams);       // 立即用新参数请求数据
};

2. 使用 useEffect 监听 params 变化自动请求

删除 onFinish 中手动调用 getTableList 的代码,改为依赖 params 的副作用。

javascript 复制代码
useEffect(() => {
  getTableList();
}, [params]); // params 变化时重新请求

const onFinish = (formValue) => {
  setParams({
    ...params,
    channel_id: formValue.channel_id,
    status: formValue.status,
    begin_pubdate: formValue.date ? formValue.date[0].format('YYYY-MM-DD') : null,
    end_pubdate: formValue.date ? formValue.date[1].format('YYYY-MM-DD') : null
  });
  // 不需要再手动调用 getTableList
};

注意:使用 useEffect 时需要确保 params 的引用变化(每次更新都创建新对象),并且首次加载也会触发,因此初始 useEffect 中的手动调用可以移除。

总结

两种方式均可解决问题。第一种更直观,请求时机完全由开发者控制;第二种更符合 React 数据流,但需注意避免额外副作用。根据你的场景选择即可。

相关推荐
LaughingZhu12 小时前
智能体经典范式构建:ReAct、Plan-and-Solve 与 Reflection
前端·react.js·前端框架
飞天狗13 小时前
长列表滚动卡顿怎么破:虚拟列表选型 + react-virtuoso 实战调优指南
react.js·性能优化
binbin_5216 小时前
React 井字棋教程:用一个小游戏理解组件和状态
前端·react.js·前端框架
张元清17 小时前
React useObjectUrl Hook:预览文件与 Blob,不留内存泄漏(2026)
javascript·react.js
真的想不出名儿20 小时前
Md编辑器整合-react
前端·react.js·编辑器
牛仔只喝牛奶1 天前
多端跨端技术选型:小程序 + H5 + App 的两栈拆分落地
react native·react.js
wear工程师2 天前
setState 到底是不是异步的?这题从 React 16 问到 18,标准答案早就变了
react.js·面试
wanghowie2 天前
LangGraph4j 落地(二)— ReAct 多步工具与 trace 扩展
前端·react.js·前端框架
csj502 天前
前端基础之《React(11)—state声明式》
前端·react.js
张元清2 天前
React useLocalStorage Hook:SSR 安全的持久化状态(2026)
javascript·react.js