redux 由useMutation()提供的RTK查询数据未定义

luaexgnf  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(158)

我似乎找不到这个具体案例的答案,我对整个JS世界有些陌生,所以希望能解释一下:
我正在使用Redux工具包(RTK)和RTK查询,所有的作品都在那里。我有它的设置,我做了一个POST请求与表单数据体类型和响应是Blob图像。
我按照文档,所以我很确定我的设置是好的。
但是,在执行以下操作时:

const [postSomeData, { data, isLoading, error, isSuccess }] =
  usePostSomeDataMutation();

字符串
然后按下按钮或采取一些行动....

await postSomeData({
  "blah":"blah"
});
       
if (isSuccess) {
  const myData = data; // undefined
}


这个函数的data总是未定义的。是的,我总是在访问data之前检查isSuccessisLoadingisError,它总是返回undefined。
需要注意的是,我将responseHandler添加到apiSlice中,它将response.blob转换为base64字符串。
因此,根据我的逻辑,data应该等于base64字符串,但它不是。
实际上如果我做以下事情

const [postSomeData, { data, isLoading, error, isSuccess }] =
  usePostSomeDataMutation();


然后按下按钮或一些动作...

const myData = await postSomeData({
  "blah":"blah"
}).unwrap(); // has my data


在这种情况下,我从“上面”的data值中得到了我没有得到的实际响应数据。为什么会这样?如果我必须自己定义data,那么data的目的是什么?

but5z9lq

but5z9lq1#

当使用Redux-Toolkit Query(RTK,RTKQ)时,所有查询和变化最初都是以未缓存的响应开始的,即没有任何data可以提供给组件,例如data是未定义的。

const [
  postSomeData,
  {
    data, // <-- undefined until first successful response is cached
    isLoading,
    error,
    isSuccess
  }
] = usePostSomeDataMutation();

字符串
你不明白的是Javascript Closures
闭包是一个函数与其周围状态(词法环境)的引用捆绑在一起(封闭)的组合。换句话说,闭包使您可以从内部函数访问外部函数的作用域。在JavaScript中,每次创建函数时都会创建闭包。
在第一个例子中,你已经关闭了回调作用域中最初未定义的data值,所以它将 * 永远 * 不会 * 成为由突变的响应值定义的。

const theCallback = async () => {
  await postSomeData({ "blah": "blah" });
   
  if (isSuccess) {
    const myData = data; // undefined from closure
  }
};


第二个例子有效的原因是因为回调等待并解包从触发器函数返回的解析的Promise,它是突变响应值(* 或错误!!*)。注意这里你还应该在try/catch中包围异步逻辑,因为任何抛出的异常和拒绝的Promise也将被解包。
范例:

const theCallback = async () => {
  try {
    const myData = await postSomeData({ "blah": "blah" }).unwrap();
    ...
  } catch(error) {
    ... catch any thrown exceptions or rejected Promises
  }
};


有关突变触发器返回值的更多详细信息/解释:

  • 处理Thunk结果

如果我必须自己定义useMutation中的data,那么它的用途是什么?
从钩子声明/解构data的目的是为了在React函数组件体中声明和范围内,例如,它可以用于渲染JSX。如果你在函数组件体中不需要它,那么就不需要从usePostSomeDataMutation声明/解构它。

相关问题