我正在 Redux 上创建一个 Reddit 客户端,并且在应用程序中触发了 2 个商店调度:
// App()
const dispatch = useDispatch();
useEffect(() => {
const stateMatch = window.location.href.match(/state=([^&]*)/);
const codeMatch = window.location.href.match(/code=([^&]*)/);
if ((stateMatch && codeMatch) || localStorage.getItem("access_token")) {
dispatch(fetchUser());
dispatch(fetchSubs());
}
});
...
Run Code Online (Sandbox Code Playgroud)
但是,我想在开始fetchUser()之前运行并完成fetchSubs(),因为前者目前似乎会破坏后者在运行时的 API 调用。我该如何解决这个问题?
试图找出实现以下目标的最佳方法:
createApicreateSlice前2个没问题!但问题是当我需要向 API 添加拦截器时(无效的身份验证 - 清除本地身份验证状态):
// api.ts
import authSlice from './authSlice';
const baseQueryWithReauth: BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError> = async (
args,
api,
extraOptions
) => {
const result = await baseQuery(args, api, extraOptions)
if (result.error?.status === 401) {
api.dispatch(authSlice.actions.clearAuth())
}
return result
}
export const api = createApi({
reducerPath: API_REDUCER_KEY,
baseQuery: baseQueryWithReauth,
endpoints: () => ({}),
})
Run Code Online (Sandbox Code Playgroud)
// authService.ts
import { User } from '../../models/User' …Run Code Online (Sandbox Code Playgroud) 我想将唯一数据添加到我的存储数组中,但在添加数据时似乎陷入困境,并且重复数据被推入数组中。我正在使用打字稿。
所以我的切片函数看起来像这样。
const initialState = {
dropDownData:{
programs: [],
years: []
}
}
Run Code Online (Sandbox Code Playgroud)
const slice = createSlice({
name:"filterSlice",
initialState: initialState,
reducers:{
updateProgram:(state, action) => {
state.dropDownData.programs = [...state.dropDownData.programs, action.payload];
}
}
});
Run Code Online (Sandbox Code Playgroud)
我以这种方式调用这个减速函数:dispatch(updateProgram(program))
所以我得到的程序是数组的形式。但我不需要程序数组中的重复数据。
那么如何更新我的减速器功能。
所以我正在对Blur 进行表单验证,并使用RTK 查询来调用api。我面临的问题是,在第一次 API 调用时,isSuccess即使 API 返回状态为 200,也会返回 false
const [validateUser, { data, isSuccess }] = authAPI.useValidateUserMutation();
const validateUserDetails = (name, event) => {
event.preventDefault();
if (event.target.value !== "") {
let fieldData = {
fieldName: name,
value: event.target.value,
};
validateUser(fieldData);
console.log("Is Success: ", isSuccess);
if (isSuccess && data.errors.status !== 200) {
console.log(data);
}
} else {
}
};
Run Code Online (Sandbox Code Playgroud)
即使状态是 API 状态是 200 成功也会返回 false 但现在如果我再次执行它将返回 true
有办法解决这个问题吗?
我尝试在 Redux-Persist 中转换我的 Redux 状态,但我不知道如何编写代码,因为我使用 mergeReducers。
这是我的商店的样子:
import { createStore, combineReducers } from 'redux'
import { usersReducer } from './users';
import { eventsReducer } from './events';
export const store = createStore(combineReducers({
users: usersReducer,
events: eventsReducer
}));
Run Code Online (Sandbox Code Playgroud)
这就是商店的样子:
const initialState = {
loggedIn: false,
thisUser: []
}
export function usersReducer(state = initialState, action) {
switch (action.type) {
case 'users/loggedIn':
return { ...state, loggedIn: action.payload }
case 'users/addUser':
return { ...state, thisUser: action.payload[0] }
case 'users/setActivated':
return { ...state, thisUser: { ...state.thisUser, …Run Code Online (Sandbox Code Playgroud) 如何在react @reduxjs/toolkit的createSlice中使用钩子将数据保存在localStorage中每当我更改主题时,我想将数据保存在localStorage中。我知道这可以直接使用 js 代码完成,但我在 useLocalStorage 挂钩方面遇到问题。
import { createSlice } from "@reduxjs/toolkit";
import useLocalStorage from "../hooks/useLocalStorage";
const initialState = {
theme: true
}
const [settings, setSettings] = useLocalStorage("settings", initialState);
export const settingsSlice = createSlice({
name: "theme",
initialState: { value: initialState },
reducers: {
setSettings: (state, action) => {
state.value = action.payload;
},
toggleTheme: (state) => {
const temp = { ...state.value, theme: !state.value.theme };
//save in localStorage
setSettings(temp);
state.value = temp;
},
},
});
export const { toggleTheme } = …Run Code Online (Sandbox Code Playgroud) 我知道,当我们尝试在 React 中添加渲染层次结构树之外的组件时,如果我们想要在页面中的其他任何内容之上弹出模型组件,我们可能需要使用 React Portal
但我无法完全理解为什么我们不把这个模型组件放在同一个层次结构树中,而是放在它的顶部并使其渲染取决于我们从react context或redux获得的变量
function App(){
const showModel ; //variable we get from redux or react context
return (<>
{showModel? </Model>:""}
<div id="main"></>
</>)
}
Run Code Online (Sandbox Code Playgroud) 我尝试在 Next.js 中使用 persistReducer,但我不断收到此错误
error - SyntaxError: Cannot use import statement outside a module
/Users/xx/node_modules/redux-persist/es/persistReducer.js:11
import { FLUSH, PAUSE, PERSIST, PURGE, REHYDRATE, DEFAULT_VERSION } from './constants';
Run Code Online (Sandbox Code Playgroud)
这是我的 _app.tsx 文件,如下所示:
<Providers>
<Container>
<Component {...pageProps} />
</Container>
</Providers>
Run Code Online (Sandbox Code Playgroud)
这是我原来的 store.ts 看起来像:
error - SyntaxError: Cannot use import statement outside a module
/Users/xx/node_modules/redux-persist/es/persistReducer.js:11
import { FLUSH, PAUSE, PERSIST, PURGE, REHYDRATE, DEFAULT_VERSION } from './constants';
Run Code Online (Sandbox Code Playgroud)
这是我尝试将其更改为:
import { configureStore, Action } from "@reduxjs/toolkit"
import { useDispatch } from "react-redux"
import {
persistStore
} from …Run Code Online (Sandbox Code Playgroud) 当我应用 createApi 自动生成的钩子时。该钩子会自动向服务器发出请求,但我只需要在特定条件下发出该请求。我尝试根据Redux文档来实现它:(https://redux-toolkit.js.org/rtk-query/usage/conditional-fetching),但没有成功。
我的实现:(src/features/posts/PostList.js)
import React, { useState } from 'react'
import { useGetPostsQuery } from '../api/apiSlice'
const PostExcerpt = ({ post }) => {
return (
<div>
<p>{post.postText}</p>
<p>
<small>{post.author}</small>
</p>
</div>
)
}
export const PostList = () => {
const [skip, setSkip] = useState(true)
const { data: posts = [], isLoading, isSuccess, isError, error } = useGetPostsQuery({ skip })
let content
if (isLoading) {
content = <h3>Posts Loading ...</h3>
} else if (isSuccess) {
content …Run Code Online (Sandbox Code Playgroud) 每次购物车页面加载时,我都必须 getAllCartItems Endpoint ,我尝试使用 useEffect 来调用它,但这会给出错误,因为我们无法在钩子内调用钩子。有没有其他方法可以在每次打开购物车页面时调用此 getAllCartItems 挂钩。
redux ×10
reactjs ×9
javascript ×4
rtk-query ×4
frontend ×1
next.js ×1
react-hooks ×1
react-native ×1
typescript ×1