reactjs - 带有 Redux 的 TypeScript。Redux Saga 如何等待 LOAD_SUCCESS 返回并保存数据以备后用
问题描述
我是使用 redux 和 redux-saga 的新手。
将操作发送到 API 时,我无法检索对象的信息。当我在“promocoesSagas”中第一次使用日志时返回null,它只是在LOAD_REQUEST成功后才返回对象,这很明显。我应该采取什么方法让我的应用程序等待接收这些数据?因为如果我调用一个
const promocoesItems = promocoesSagas.data.item;
应用程序因“LOAD_REQUEST”尚未加载数据而中断,第一次返回null。 第一次调用 尝试访问值
我的 useEffect 钩子:
const List = () => {
...
const promocoesSagas = useSelector((state: AppState) => state.promocoes);
console.log(promocoesSagas);
const promocoesItem = promocoesSagas.data.items;
console.log(promocoesItem);
const dispatch = useDispatch<Dispatch<PromocoesActions>>();
useEffect(() => {
(async () => {
setIsloading(true);
try {
dispatch({ type: PromocoesActionTypes.LOAD_REQUEST, payload: query });
} catch (error) {
const errorResult: ErrorResult = error;
if (
errorResult.result != null &&
errorResult.result.statusCode === 403
) {
push('/error-403');
return;
}
message.error(errorResult.message);
}
setIsloading(false);
})();
}, [query, refetch]);
return (...)}
动作.ts
const loadPromocoesAsync = createAsyncAction(
PromocoesActionTypes.LOAD_REQUEST,
PromocoesActionTypes.LOAD_SUCCESS,
PromocoesActionTypes.LOAD_FAILURE,
)<PromocoesQuery, FetchResult<PromocoesModel>, undefined>();
export { loadPromocoesAsync };
减速器
const INITIAL_STATE: PromocoesState = {
data: null,
error: false,
loading: false,
};
const reducer: Reducer<PromocoesState> = (
state = INITIAL_STATE,
action: PromocoesActions,
) => {
switch (action.type) {
case PromocoesActionTypes.LOAD_REQUEST:
return { ...state, loading: true };
case PromocoesActionTypes.LOAD_SUCCESS:
return { ...state, loading: false, error: false, data: action.payload };
case PromocoesActionTypes.LOAD_FAILURE:
return { ...state, loading: false, error: true };
default:
return state;
}
};
sagas.ts
function* load(action: ReturnType<typeof loadPromocoesAsync.request>) {
try {
const query = action.payload;
const response: FetchResult<PromocoesModel> = yield call(
api.getPromocoes,
query,
);
yield put(loadPromocoesAsync.success(response));
} catch (err) {
yield put(loadPromocoesAsync.failure());
}
}
export { load };
类型.ts
type PromocoesActions = ActionType<typeof promocoesActions>;
enum PromocoesActionTypes {
LOAD_REQUEST = 'LOAD_REQUEST',
LOAD_SUCCESS = 'LOAD_SUCCESS',
LOAD_FAILURE = 'LOAD_FAILURE',
}
interface PromocoesState {
readonly data: FetchResult<PromocoesModel> | null;
readonly loading: boolean;
readonly error: boolean;
}
export { PromocoesActions, PromocoesActionTypes, PromocoesState };
根减速器
const rootReducer = combineReducers({
promocoes,
});
export type AppState = ReturnType<typeof rootReducer>;
export default rootReducer;
根传奇
export default function* rootSaga() {
return yield all([takeLatest(loadPromocoesAsync.request, load)]);
}
解决方案
你几乎准备好了,你只需要在 react 应用程序中处理你的 redux 变量,我建议在List组件中做这样的事情,记住你的 promocoes reducer 已经有 loading 或 error 变量:
// Here you grab the values from the store, you don't need any local state.
const {data, loading, error, } = useSelector((state: AppState) => state.promocoes);
const dispatch = useDispatch<Dispatch<PromocoesActions>>();
// Your useEffect can be simplified, because your api call is already handled by the saga
useEffect(() => {
dispatch({ type: PromocoesActionTypes.LOAD_REQUEST, payload: query });
}, [query, refetch]);
if (loading) return <p>Loading...</p>
if (error) return message.error(errorResult.message)
// Assuming data is an array
return data && data.length > 0 && (
// Your component
)
推荐阅读
- textures - Vulkan 采样器未显示正确的边框颜色
- sql-server - 使用时间戳将 sp_who 的结果多次插入表中
- python-3.x - '\r' 字符串回车函数未按预期工作
- javascript - 父状态更改后反应子不更新
- python - 找不到通过 requests.py 获取 Twitch API 信息的方法
- java-8 - Java jackson反序列化json - 获取符号“=”而不是“:”
- python - 为什么我无法安装 discord.py?
- laravel - New Tenancy 1.x Laravel 创建数据库后如何插入数据
- celery - 只有当所有子任务都成功完成后才能使任务发布成功?
- r - 如何在 .rmd 文件中获取部分名称?