Redux Toolkit搭配Reselect在fetch请求场景下的使用方法咨询
Reselect 的使用和请求是同步还是异步没有本质区别,它的核心作用是对 Redux 状态的派生计算结果做缓存,只关心 Redux Store 内的状态变化,不需要关心状态是同步更新还是异步请求触发更新的。
结合你给出的代码,具体用法如下:
第一步:创建独立的选择器文件
你可以单独新建 authSelectors.js 统一管理所有和用户认证相关的选择器,避免逻辑散落在各个组件中:
// 如果你用 Redux Toolkit,内置了 reselect,直接从 @reduxjs/toolkit 导入即可 import { createSelector } from '@reduxjs/toolkit' // 基础输入选择器:直接获取user状态切片 const selectUserSlice = (state) => state.user // 派生选择器:获取认证请求加载状态 export const selectAuthLoading = createSelector( [selectUserSlice], userState => userState.loading ) // 派生选择器:获取登录用户数据 export const selectAuthUserData = createSelector( [selectUserSlice], userState => userState.data ) // 派生选择器:获取认证错误信息 export const selectAuthError = createSelector( [selectUserSlice], userState => userState.error ) // 还可以扩展更复杂的派生逻辑,比如判断用户是否已登录 export const selectIsLoggedIn = createSelector( [selectAuthUserData], // 注意:你当前authSlice初始state.data是数组,但登录接口返回的user应该是对象,建议把初始值改成{}或者null,这里判断逻辑可以对应调整 userData => Object.keys(userData || {}).length > 0 )
第二步:在组件中配合 useSelector 使用
直接在组件中导入对应的选择器,传入 useSelector 即可使用,和你之前直接传匿名函数的用法一致:
// 导入刚才定义的选择器 import { selectAuthLoading, selectAuthError } from './authSelectors' const Login = ({ navigation, route }) => { const dispatch = useDispatch(); // 调用选择器获取对应状态 const authLoading = useSelector(selectAuthLoading) const authError = useSelector(selectAuthError) const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [passwordShown, setPasswordShown] = useState(true); const handleGoBack = () => { navigation.goBack(); }; const handleLogin = async () => { const payload = { email, password }; dispatch(request(payload)); }; return ( <View> {/* 可以直接用拿到的状态控制UI展示 */} {authError && <Text style={{color: 'red'}}>{authError.message}</Text>} <TouchableOpacity onPress={handleLogin} disabled={authLoading}> <Text>{authLoading ? '登录中...' : 'click to fetch!'}</Text> </TouchableOpacity> </View> ) }
用法说明
整个异步流程的状态流转和 Reselect 的触发逻辑是:
- 你点击登录按钮 dispatch
requestaction - Saga 捕获 action 后调用登录接口
- 接口返回后,Saga put
authSuccess/authFailureaction 更新 Redux 中user切片的状态 - Reselect 检测到依赖的
user切片发生变化,重新计算对应派生状态的值返回 useSelector检测到返回值发生变化,触发组件重渲染更新 UI
这种写法的优势是:
- 所有派生状态的计算逻辑统一维护,多组件复用时不需要重复写取值逻辑
- 只要选择器依赖的状态没有变化,Reselect 会直接返回缓存的结果,不会重复计算,避免不必要的组件重渲染
- 状态取值逻辑和组件完全解耦,后续如果调整 Redux 里的状态结构,只需要修改选择器即可,不需要改动所有用到对应状态的组件
小优化提示
你当前 authSlice 的初始状态里 data 是数组,但 authSuccess 里赋值的是接口返回的 data.user,通常用户信息是对象类型,建议把初始 data 的值从 [] 改成 {} 或者 null,避免后续判断逻辑出错。
内容的提问来源于stack exchange,提问作者Datastores11
相关产品推荐
相关产品推荐

