初学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 数据流,但需注意避免额外副作用。根据你的场景选择即可。

相关推荐
老黑3 小时前
开源工具 AIDA:给 AI 辅助开发加一个数据采集层,让 AI 从错误中自动学习(Glama 3A 认证)
前端·react.js·ai·nodejs·cursor·vibe coding·claude code
Highcharts.js7 小时前
React 开发者的图表库生态:Highcharts React
前端·react.js·前端框架
钛态8 小时前
Flutter 三方库 react 泛前端核心范式框架鸿蒙原生层生态级双向超能适配:跨时空重塑响应式单向数据流拓扑与高度精密生命周期树引擎解耦视图渲染控制中枢(适配鸿蒙 HarmonyOS ohos)
前端·flutter·react.js
米饭同学i9 小时前
基于腾讯云COS的小程序素材上传功能实现
前端·javascript·react.js
哈__9 小时前
ReactNative项目OpenHarmony三方库集成实战:react-native-fingerprint-scanner
javascript·react native·react.js
装不满的克莱因瓶10 小时前
React Native vs Flutter:一次深入到底的性能对比分析(含原理 + 实战)
javascript·flutter·react native·react.js·app·移动端
qq_3680196613 小时前
用 react 的react-syntax-highlighter 实现语法高亮、行号与多行错误行高亮
前端·react.js·前端框架
社恐的下水道蟑螂13 小时前
从奶茶店彻底搞懂 SSR!从零到拿捏服务端渲染,看完面试吹牛逼不卡壳
前端·react.js·性能优化
tzy23315 小时前
Vue和React之争
前端·vue.js·react.js