我正在使用本地 json 数据来测试我的 RTK 查询查询,但是我在 selectById 和标准化数据方面遇到很多麻烦。 selectById 之前的所有内容似乎都很好,responseData 包括必要的数据,并且 id 匹配,所以我真的迷失了问题所在。任何帮助将不胜感激,谢谢。 (我将确保包含我需要的所有内容,如果我遗漏了任何重要的内容,请告诉我)。
Json数据
{
"tasks": [
{
"id": "4",
"title": "example title 3",
"description": "dsa adasdas dsa dsadas dasdas ",
"assignedTo": "katie",
"completeBy": "March 01, 2024 11:51:33 PM",
"timeCreated": "February 29, 2024 11:51:48 PM",
"timeUpdated": "March 01, 2024 5:04:27 PM"
}
]
}
任务切片
import {createSelector, createEntityAdapter} from "@reduxjs/toolkit";
import { apiSlice } from "../services/tasks";
const tasksAdapter = createEntityAdapter({})//get normalized state ids array and entities like a map kinda
const initialState = tasksAdapter.getInitialState()
export const tasksApiSlice = apiSlice.injectEndpoints({
endpoints: builder => ({
getTasks: builder.query({
query: () => '/tasks',
validateStatus: (response, result) => {
return response.status === 200 && !result.isError
},
transformResponse: responseData => {
console.log("responeData", responseData)
return tasksAdapter.setAll(initialState, responseData);
},
providesTags: (result, error, arg) => {
if (result?.ids) {//a fail safe
return [
{ type: 'Task', id: 'LIST' },
...result.ids.map(id => ({ type: 'Task', id }))
]
} else return [{ type: 'Task', id: 'LIST' }]
}
}),
})
})
export const {
useGetTasksQuery,
} = tasksApiSlice
// returns the query result object
export const selectTaskResult = tasksApiSlice.endpoints.getTasks.select()
// creates memoized selector for optimization
export const selectTasksData = createSelector(
selectTaskResult,
tasksResults => tasksResults.data // normalized state object with ids & entities
)
//getSelectors creates these selectors and we rename them with aliases using destructuring
export const {
selectAll: selectAllTasks,
selectById: selectTaskById,
selectIds: selectTaskIds
// Pass in a selector that returns the users slice of state
} = tasksAdapter.getSelectors(state => selectTasksData(state) ?? initialState)
首页
import React from 'react';
import TaskContainer from './TaskContainer';
import { useGetTasksQuery } from './tasksSlice';
const Home = () => {
const { data: tasks, isLoading, isSuccess, isError, error } = useGetTasksQuery('', {
pollingInterval: 60000,
refetchOnFocus: true,
refetchOnMountOrArgChange: true
});
let content;
if (isLoading) {
content = <p>Loading...</p>;
} else if (isError) {
content = <p className="errmsg">{error?.data?.message}</p>;
} else if (isSuccess) {
const taskIds = tasks?.ids; // Get the array of task ids from the normalized data
console.log(taskIds)
if (taskIds && taskIds.length > 0) {
content = (
<div>
<h1>Home</h1>
{taskIds.map(taskId => (
<TaskContainer key={taskId} id={taskId} />
))}
</div>
);
} else {
content = <p>No tasks found.</p>;
}
}
return content;
};
export default Home;
任务容器
import React from 'react';
import { selectTaskById } from './tasksSlice';
import { useSelector } from 'react-redux';
const TaskContainer = ({ id }) => {
const task = useSelector(state => selectTaskById(state, id));
console.log(task)
return (
<div>
<p onClick={navTaskPage}>Title: {task ? task.title : 'Loading...'}</p>
{/* Additional task details can be rendered similarly */}
</div>
);
};
export default TaskContainer;
响应数据 响应数据是什么样的
我尝试参考文档来尝试了解可能导致问题的原因,但并没有真正解决任何问题。
在taskContanier中,您可以将useGetTasksQuery与selectFromResult参数一起使用,而不是使用selectTaskById,即useSelector
const {task}=useGetTasksQuery('',{
selectFromResult:({data})=>({
task:data?.entities[id]
})
})