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
相关产品推荐
相关产品推荐

