基于RTK Query在组件间过滤Todo查询结果的优化方案咨询
Todo应用过滤逻辑优化方案
你当前基于Next.js 13(App目录)、Prisma、RTK Query等技术栈实现的Todo过滤逻辑,存在可以优化的空间,以下是更简洁高效的实现方案:
现有实现的问题点
- 额外维护了
todos状态,每次filter或data变化时需要通过useEffect更新,增加了不必要的状态更新和渲染触发 - filter初始值为
null,和Tabs组件的defaultValue='all'不匹配,可能导致初始逻辑混乱 - 部分类型定义使用
any,降低了代码的类型安全性 - 过滤逻辑的分支判断可以更简洁
优化后的实现方案
核心思路是移除冗余状态,用useMemo实时计算过滤后的Todo列表,避免不必要的状态更新,同时统一逻辑、优化类型:
1. 优化TodoPage组件
'use client'; import AddTodoSheet from '@/components/AddTodoSheet'; import Filter from '@/components/Filter'; import TodoList from '@/components/TodoList'; import { Separator } from '@/components/ui/separator'; import { useGetTodosQuery } from '@/redux/features/api/apiSlice'; import { Todo } from '@prisma/client'; import React from 'react'; const TodoPage = () => { const { data, isLoading, isError } = useGetTodosQuery({}); // 统一初始值为'all',和Tabs的defaultValue匹配 const [filter, setFilter] = React.useState<'all' | 'completed' | 'waiting'>('all'); // 用useMemo实时计算过滤后的列表,仅在data或filter变化时重新计算 const filteredTodos = React.useMemo(() => { if (!data) return []; switch (filter) { case 'completed': return data.filter((todo: Todo) => todo.isCompleted); case 'waiting': return data.filter((todo: Todo) => !todo.isCompleted); case 'all': default: return data; } }, [data, filter]); return ( <div> <div className='flex items-center justify-between mt-2'> <Filter filter={filter} setFilter={setFilter} /> <AddTodoSheet /> </div> <Separator className='my-2' /> {!isLoading && <TodoList data={filteredTodos} />} </div> ); }; export default TodoPage;
2. 优化TodoList组件(完善类型定义)
import React from 'react'; import TodoItem from './TodoItem'; import { Todo } from '@prisma/client'; // 明确data的类型,避免any const TodoList = ({ data }: { data: Todo[] }) => { return ( <div> {data.map((todo) => ( <TodoItem key={todo.id.toString()} todo={todo} /> ))} </div> ); }; export default TodoList;
3. 优化Filter组件(完善类型定义)
import React from 'react'; import { Tabs, TabsList, TabsTrigger } from './ui/tabs'; // 明确props的类型 type FilterProps = { filter: 'all' | 'completed' | 'waiting'; setFilter: (value: 'all' | 'completed' | 'waiting') => void; }; const Filter = ({ filter, setFilter }: FilterProps) => { return ( <Tabs defaultValue='all' value={filter} onValueChange={setFilter}> <TabsList> <TabsTrigger value='all'>All</TabsTrigger> <TabsTrigger value='completed'>Completed</TabsTrigger> <TabsTrigger value='waiting'>Waiting</TabsTrigger> </TabsList> </Tabs> ); }; export default Filter;
优化点说明
- 用useMemo替代useState+useEffect:仅在依赖项(data或filter)变化时才重新计算过滤列表,避免了不必要的状态更新和组件重渲染,性能更优
- 统一初始值:filter初始值设为'all',和Tabs组件的默认值保持一致,避免初始状态的逻辑混乱
- 完善类型定义:移除any类型,明确props和状态的类型,提升代码的可维护性和类型安全性
- 简化过滤逻辑:用switch-case替代多个if判断,逻辑更清晰易读
内容的提问来源于stack exchange,提问作者AdylshaY
相关产品推荐
相关产品推荐

