Electron+React集成tRPC并对接Redux Toolkit的技术咨询
Electron+React中tRPC与Redux Toolkit整合方案
1. tRPC与Redux Toolkit全局状态结合
核心思路是通过Redux异步Thunk调用tRPC客户端方法,将请求结果同步到全局状态;或是在tRPC的回调中触发Redux Action更新状态,满足跨组件共享数据的需求。
示例:在Redux Thunk中调用tRPC
先初始化tRPC客户端:
// utils/trpc.ts import { createTRPCReact } from '@trpc/react-query'; import type { AppRouter } from '../server/router'; export const trpc = createTRPCReact<AppRouter>();
在Redux Slice中定义异步Thunk与状态:
// features/user/userSlice.ts import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; import { trpc } from '../../utils/trpc'; // 异步Thunk:调用tRPC查询用户信息 export const fetchUser = createAsyncThunk( 'user/fetchUser', async (userId: string, { extra }) => { const trpcClient = extra.trpc; const response = await trpcClient.user.getById.query(userId); return response; } ); const userSlice = createSlice({ name: 'user', initialState: { data: null, loading: false, error: null, }, reducers: {}, extraReducers: (builder) => { builder .addCase(fetchUser.pending, (state) => { state.loading = true; state.error = null; }) .addCase(fetchUser.fulfilled, (state, action) => { state.loading = false; state.data = action.payload; }) .addCase(fetchUser.rejected, (state, action) => { state.loading = false; state.error = action.error.message || '请求失败'; }); }, }); export default userSlice.reducer;
配置Redux Store时注入tRPC客户端:
// app/store.ts import { configureStore } from '@reduxjs/toolkit'; import userReducer from '../features/user/userSlice'; import { trpc } from '../utils/trpc'; import { httpBatchLink } from '@trpc/client'; const trpcClient = trpc.createClient({ links: [ httpBatchLink({ url: 'http://localhost:3000/trpc', // 你的后端tRPC地址 }), ], }); export const store = configureStore({ reducer: { user: userReducer, }, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ thunk: { extraArgument: { trpc: trpcClient }, }, }), });
2. tRPC自带状态与Redux Thunk状态的配合
无需重复维护两套状态,推荐二选一:
- 优先用tRPC自带状态:如果组件仅需当前请求的状态与数据,直接使用
tRPC.useQuery/useMutation返回的isLoading、error,避免冗余状态同步。 - 统一用Redux状态:若需全局共享请求状态,可在Thunk中手动处理状态,或在tRPC回调中触发Redux Action:
示例:tRPC回调同步Redux状态
// 组件中调用tRPC并同步结果到Redux import { trpc } from '../utils/trpc'; import { useDispatch } from 'react-redux'; import { setUser } from '../features/user/userSlice'; function UserProfile() { const dispatch = useDispatch(); const { data, isLoading, error } = trpc.user.getById.useQuery('123', { onSuccess: (user) => { dispatch(setUser(user)); }, }); if (isLoading) return <div>加载中...</div>; if (error) return <div>请求失败</div>; return <div>用户名:{data?.name}</div>; }
3. 避免tRPC Hook组件内混乱:封装自定义Hook
将tRPC调用逻辑抽离到独立的自定义Hook中,组件仅关注业务渲染,减少重复代码并提升可维护性:
示例:封装用户相关tRPC Hook
// hooks/useUser.ts import { trpc } from '../utils/trpc'; // 查询用户信息的Hook export function useUser(userId: string) { const { data, isLoading, error, refetch } = trpc.user.getById.useQuery(userId, { staleTime: 5 * 60 * 1000, // 统一配置5分钟缓存 }); return { user: data, isLoading, error, refetchUser: refetch, }; } // 修改用户信息的Mutation Hook export function useUpdateUser() { const mutation = trpc.user.update.useMutation({ onSuccess: () => { trpc.user.getById.invalidate(); // 成功后自动刷新用户数据缓存 }, }); return { updateUser: mutation.mutate, isUpdating: mutation.isLoading, updateError: mutation.error, }; }
组件中使用封装后的Hook
function UserProfile() { const { user, isLoading, error } = useUser('123'); const { updateUser, isUpdating } = useUpdateUser(); const handleUpdate = () => { updateUser({ id: '123', name: '新名字' }); }; if (isLoading) return <div>加载中...</div>; if (error) return <div>请求失败</div>; return ( <div> <p>用户名:{user?.name}</p> <button onClick={handleUpdate} disabled={isUpdating}> {isUpdating ? '更新中...' : '修改名字'} </button> </div> ); }
内容的提问来源于stack exchange,提问作者KhaliLounis
相关产品推荐
相关产品推荐

