当fetchUserById()创建时,其输出响应被定义。
const fetchUserById = createAsyncThunk<{user: UserInterface, id: number}, number>(
'users/fetchByIdStatus',
async (userId) => {
const response = await userAPI.fetchById(userId)
return {user: response.data, id: userId}
}
);
const userSlice = createSlice({
name: "users",
initialState: [],
reducers: {},
extraReducers: (builder) => {
builder.addCase(fetchUserById.pending, (state, { payload }) => {
// how I configured custom value for this payload?
// I need to send the user id.
});
builder.addCase(fetchUserById.fulfilled, (state, {payload}) => {
/**
* @var {UserInterface} user
* @var {number} …Run Code Online (Sandbox Code Playgroud) 有没有办法将createAsyncThunk与 Firebase 侦听器一起使用,例如firestore.collection.onSnapshot?
它可能不起作用,因为 onSnapshot 的工作方式(它是一个侦听器,每次 firestore 更新时都会接收数据并触发回调,并返回一个取消订阅侦听器的函数)。我尝试实现 createAsyncThunk 但无法弄清楚。
这是我当前的 thunk 实现,它确实有效:
const listenerUnsubscribeList = [];
export function fetchProjects() {
return dispatch => {
dispatch(fetchProjectsPending());
const unsubscribe = firestore
.collection('projects')
.onSnapshot(
snapshot => { dispatch(fetchProjectsFulfilled(snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })))) },
error => { dispatch(fetchProjectsError(error)) },
);
listenerUnsubscribeList.push(unsubscribe);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我对 createAsyncThunk 的尝试,但不起作用。我得到了database/fetchProjects/pending,database/fetchProjects/fulfilled但有效负载是undefined
const listenerUnsubscribeList = [];
export const fetchProjects = createAsyncThunk(
'database/fetchProjects',
async (_, thunkAPI) => {
const …Run Code Online (Sandbox Code Playgroud) 每当我在 Redux 存储中存储不可序列化的值时,我都会收到以下警告:
在下面的示例中,我存储了Firestore.TimestampRedux 状态。它也发生在Date物体上。
在状态中检测到不可序列化的值,路径为:blogPost.createdAt。值:t {秒:1583488258,纳秒:805000000}
看一下处理此操作类型的减速器:LOAD_BLOGPOST_SUCCESS。(参见https://redux.js.org/faq/organizing-state#can-i-put-functions-promises-or-other-non-serialized-items-in-my-store-state)
这就是医生的说法:
我可以将函数、承诺或其他不可序列化的项目放入我的存储状态中吗?
强烈建议您只将普通的可序列化对象、数组和基元放入存储中。从技术上讲,可以将不可序列化的项目插入到存储中,但这样做可能会破坏存储内容的持久性和重新水化的能力,并且会干扰时间旅行调试。
如果您对持久性和时间旅行调试等可能无法按预期工作的事情感到满意,那么完全欢迎您将不可序列化的项目放入 Redux 存储中。最终,这是您的应用程序,如何实现它取决于您。与 Redux 的许多其他事情一样,只要确保您了解其中涉及的权衡即可。
我从上面的文档摘录中不太明白。我认为这有点模糊。有人能更详细地解释一下,通过向 Redux 状态添加不可序列化的数据,我们到底可能/将会损失什么吗?
不同数据类型的结果是否不同?例如: a Promise、 afunction (ex: a React component)和 aDate会导致不同的问题吗?肯定会带来问题吗?或者它是可能发生或可能不会发生的事情吗?
保存和补充商店内容的能力意味着什么?这是否意味着它可能会破坏我的应用程序的代码,或者我们只讨论开发工具调试?
更新
刚刚从 Redux Toolkit 中找到了另一篇文档:使用不可序列化数据。
处理不可序列化的数据
Redux 的核心使用原则之一是不应将不可序列化的值放入状态或操作中。
然而,像大多数规则一样,也有例外。有时您可能必须处理需要接受不可序列化数据的操作。应该很少这样做,并且仅在必要时才这样做,并且这些不可序列化的有效负载不应该通过减速器进入您的应用程序状态。
可序列化开发检查中间件会在检测到操作或状态中的不可序列化值时自动发出警告。我们鼓励您保持此中间件处于活动状态,以帮助避免意外犯错误。但是,如果您确实需要关闭这些警告,则可以通过将其配置为忽略特定操作类型或操作和状态中的字段来自定义中间件:
看来本节教您如何忽略在操作中使用不可序列化值的警告,但它也说它不应该进入状态,对吧?
我一整天都在与这个问题作斗争,非常感谢任何帮助。
我有一个使用 Redux Toolkit 和 createSlice 构建的 redux 商店,如下所示:
const initialState = {
analiticaNumber: "",
animal: {},
tests: [{ key: "G9116", value: "DERMATOFITOS PCR/ MUESTRA" }],
};
const PeticionSlice = createSlice({
name: "peticion",
initialState,
reducers: {
addTest: (state, action) => {
state.tests.push(action.payload);
},
},
});
export const { addTest: addTestActionCreator } = PeticionSlice.actions;
export const testsArray = (state) => state.Peticion.tests;
export default PeticionSlice.reducer;
Run Code Online (Sandbox Code Playgroud)
我还有一个根减速器,它导入其余的切片并如此命名它们
import { combineReducers } from "redux";
import NavigationSlice from "./NavigationSlice";
const RootReducer = combineReducers({
Peticion: PeticionSlice, …Run Code Online (Sandbox Code Playgroud) 我正在使用 typescript 和 redux-toolkit (主要使用 createSlice)开发我的第一个应用程序。
看起来我正在使用今天被认为是良好实践的东西,但最终我发现它并不真正具有可读性(我指出我是一名经验丰富的开发人员,并且我练习过许多其他语言。刚刚接触 React Native ,然后我习惯了良好的编码实践和记录良好的代码),并且找不到从代码和注释生成有效文档的好方法(我尝试过 typedoc)。
有人对此有什么建议吗?最好是一个易于阅读的示例 redux-toolkit 切片文件?
为了说明这一点,下面是我的文件今天的样子的示例。我向减速器“refreshEventsList”添加了注释,但 typedoc 未将其检测为文档。
import {createAsyncThunk, createSlice, PayloadAction} from '@reduxjs/toolkit';
import {callAPI} from '../../api/APIManager';
export interface EventType {
id: string;
title: string;
}
interface EventsState {
events: EventType[];
}
const initialState = {events: []} as EventsState;
/**
* Load all events and update intern events data
*/
export const loadEvents = createAsyncThunk('events/fetchAll', async () => {
const response = await callAPI({path: 'api/test'});
return response.data as EventType[];
}); …Run Code Online (Sandbox Code Playgroud) 我正在createSlice这样使用:
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
const initialState = {} as Order;
const order = createSlice({
name: 'order',
initialState,
reducers: {
setOrder: (_state, { payload }: PayloadAction<Order | null>) => payload,
},
});
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
Run Code Online (Sandbox Code Playgroud)Type 'SalesOrder | null' is not assignable to type 'void | SalesOrder | WritableDraft<SalesOrder>'. Type 'null' is not assignable to type 'void | SalesOrder | WritableDraft<SalesOrder>'.ts(2322)
当我将鼠标悬停在该函数上时,我得到以下类型:
function(_state: WritableDraft<SalesOrder>, { payload }: PayloadAction<SalesOrder | null>): SalesOrder | null
Run Code Online (Sandbox Code Playgroud)
我该如何解决?我希望该值为Order或null …
我正在使用 redux-toolkit,并尝试发送一个 thunk。我正在使用的调度函数看起来像这样,这直接取自文档。eslint 抱怨缺少返回类型,知道它应该是什么吗?
export const useAppDispatch = () => useDispatch<AppDispatch>();
Run Code Online (Sandbox Code Playgroud)
此外,我得到了同样的错误,如这个问题How to split an Action or a ThunkAction (in TypeScript, with redux-thunk)? ,但据我了解,没有真正的解决方案。
所以如果我得到这样的代码:
export const fetchSomeThing = createAsyncThunk<SomeType[]>('someThing/fetch', async () => {
const someClient = useSomeClient();
const someThing: SomeType[] = await someClient.listSomething();
return someThing;
});
// I also tried typing dispatch as AppDispatch here explicitly, but it gives me the same error
const dispatch = useAppDispatch();
dispatch(fetchSomeThing()) //This gives an error: Property 'type' is missing in type …Run Code Online (Sandbox Code Playgroud) 如何正确拒绝createAsyncThunk. 我有一个异步函数来检查邮件地址是否已存在。如果没有注册的邮件地址,则该函数的响应为空字符串;如果用户存在,则该函数的响应为注册用户的用户对象。
export const checkIfEmailExists = createAsyncThunk(
"user/checkIfEmailExists",
async (mail) => {
const response = await mailExists(mail).promise();
if (response.user && response.user.length > 0) {
reject();
} else {
resolve();
}
}
);
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,数据都会返回并且不会发生错误。createAsyncThunk在这种情况下我该如何拒绝?
我正在从 Redux 迁移到 Redux Toolkit。我这里的简化代码是使用 lodash/debounce 进行去抖更新。
import debounce from "lodash/debounce";
const updateApplication = async (app, dispatch) => {
const state = getState();
try {
const result = await update(app);
dispatch({
type: UPDATE,
result: result
});
} catch (err) {
console.log(err);
}
};
export default debounce(updateThunk, 2000);
Run Code Online (Sandbox Code Playgroud)
问题是当我转到 createAsyncThunk 时它不会被执行。
const updateApp = createAction("app/update");
const updateApplication = createAsyncThunk(
"app/updateDebounced",
async (app, { dispatch }) => {
try {
const result = await update(app);
dispatch(updateApp(result))
);
}
} catch (err) { …Run Code Online (Sandbox Code Playgroud) 有人可以帮助我使用 creatApi 和 redux 工具包中的查询实现来实现去抖功能。
提前致谢。
redux-toolkit ×10
redux ×9
reactjs ×5
typescript ×3
javascript ×2
react-redux ×2
firebase ×1
jsdoc ×1
redux-thunk ×1
rtk-query ×1