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

React Native:RTK Query返回null响应,Fetch API实现正常

问题:RTK Query重构登录验证时返回null并报错"Cannot read property 'headers' of null"

我先用Fetch API实现了登录验证,测试正常。换成Redux RTK Query重构后,得到null响应,报错如下:

LOG  response 
LOG  null 
ERROR  处理端点"authenticateUser"的请求时发生未处理错误。未处理错误情况下,不会"提供"或"失效"任何标签。[TypeError: Cannot read property 'headers' of null]

可正常运行的Fetch API代码

const url = 'https://<cannotShowUrl>/Login?redirect=none';

const authenticate = (municipality, profileName, password) => {
  const form = {
    kommune: municipality,
    benutzername: profileName,
    passwort: password,
  };

  const urlencodedForm = Object.keys(form)
    .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(form[key])}`)
    .join('&');

  return fetch(url, {
    method: 'POST',
    headers: {
      Accept:
        'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: urlencodedForm,
  })
    .then((response) => response.headers.get('Set-Cookie'))
    .then((cookie) => {
      const ID = cookie.match(/ID=([^;]*)/)?.[1];

      if (!ID)
        throw new Error('Invalid credentials');

      return ID;
    })
    .catch((error) => {
      console.error(`Error during login: ${error.message}`);
      return error;
    });
};

export { authenticate };

无法正常工作的RTK Query重构代码

const url = '/Login?redirect=none';
export const loginApiSlice = createApi({
  reducerPath: 'loginApiSlice',
  baseQuery: fetchBaseQuery({ baseUrl: 'https://<cannotShowUrl>' }),
  endpoints: (builder) => ({
    authenticateUser: builder.mutation({
      query: (credentials) => {
        const form = {
          kommune: credentials.municipality,
          benutzername: credentials.profileName,
          passwort: credentials.password,
        };

        const urlencodedForm = Object.keys(form)
          .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(form[key])}`)
          .join('&');

        console.log(urlencodedForm);

        return {
          url,
          method: 'POST',
          headers: {
            Accept:
              'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
            'Content-Type': 'application/x-www-form-urlencoded',
          },
          body: urlencodedForm,
        };
      },
      transformResponse: (response) => {
        console.log('response');
        console.log(response);
        const cookie = response.headers.get('Set-Cookie');
        const ID = cookie?.match(/ID=([^;]*)/)?.[1];

        if (!ID) {
          console.log('error');
          throw new Error('Credentials are not valid');
        }

        return ID;
      },
      transformErrorResponse(response, meta, arg) {
        console.log('error');
        console.log(response);
      },
    }),
  }),
});

export const { useAuthenticateUserMutation } = loginApiSlice;

使用的版本

"@reduxjs/toolkit": "^1.9.5",
"react-redux": "^8.1.1",
"react-native": "0.71.11",

请问我哪里操作出错了?


解答

问题核心是RTK Query的fetchBaseQuery默认会自动解析响应体(比如JSON、文本),不会直接返回原始的Response对象。你在transformResponse里直接访问response.headers,但此时response是解析后的响应内容(如果响应体为空就会是null),自然找不到headers属性。

要获取响应头,需要利用transformResponse的第二个参数meta,它包含了原始的响应信息。修改后的代码如下:

transformResponse: (response, meta) => {
  console.log('response body:', response);
  // 从meta中获取原始Response对象
  const cookie = meta.response.headers.get('Set-Cookie');
  const ID = cookie?.match(/ID=([^;]*)/)?.[1];

  if (!ID) {
    console.log('error');
    throw new Error('Credentials are not valid');
  }

  return ID;
},

额外注意两点:

  • 即使后端返回无内容的响应(如204状态码),response会是null,但meta.response依然存在,不影响获取headers
  • 不要给fetchBaseQuery配置responseHandler修改默认解析行为,否则需要对应调整获取headers的逻辑

内容的提问来源于stack exchange,提问作者user22272238

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 06:45:25