我对整个 React 和 Redux 生态系统相当陌生,我试图了解在使用 Redux 工具包时何时以及为何使用额外的减速器,而不是直接在异步 thunk 中分派操作。
最好用一个显示这两种解决方案的示例来解释:
auth.slice.ts
// ...
export const login = createAsyncThunk<LoginResponse, LoginData>(
'auth/login',
async ({ email, password }, thunkAPI) => {
const data = await AuthService.login(email, password);
// Extract user info from login response which holds other information as well
// in which we're not interested in the auth slice...
const userInfo = loginResponseToUserInfo(data);
LocalStorageService.storeUserInfo(userInfo);
// Return the whole login response as we're interested in the other data
// besides the …Run Code Online (Sandbox Code Playgroud) 目前,我正在研究 React Native 并使用 Redux
我遇到一个问题,在调度减速器时,它说不是一个函数。
这是我配置商店的方式
import { configureStore } from "@reduxjs/toolkit";
import navReducer from "./slices/navSlice";
export const store = configureStore({
reducer: {
nav: navReducer,
},
});
Run Code Online (Sandbox Code Playgroud)
这是我的减速机
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
origin: null,
destination: null,
travelTimeInformation: null,
};
export const navSlice = createSlice({
name: "nav",
initialState,
reducer: {
setOrigin: (state, action) => {
state.origin = action.payload;
},
setDestination: (state, action) => {
state.destination = action.payload;
},
setTravelTimeInformation: (state, action) => {
state.travelTimeInformation …Run Code Online (Sandbox Code Playgroud) 当我在extraReducers切片内部添加特定操作时,出现以下错误:
Uncaught TypeError: Cannot read properties of undefined (reading 'type')。
例子:
import { createSlice } from '@reduxjs/toolkit'
export const mySlice = createSlice({
name: 'name',
initialState,
extraReducers: (builder) => {
// If I console.log action2 here, it turns out to be undefined
builder.addCase(action1, () => ...)
builder.addCase(action2, () => ...) // when I add this specific action I get the error.
},
reducers: {
...
},
})
Run Code Online (Sandbox Code Playgroud)
action2的定义类似于action1另一个文件中的 :
import { createAction } from '@reduxjs/toolkit' …Run Code Online (Sandbox Code Playgroud) Redux中reducer的一条规则是:我们应该将状态视为只读,并返回一个新对象作为新状态。
但有一个灰色地带:它必须严格返回一个新对象作为状态,还是我们可以返回相同的状态对象?
看来通过查看常见代码,例如:
function favoriteColors(state, action) {
if (state === undefined) {
state = [];
}
if (action.type === 'ADD') {
return Array.from(new Set([...state, action.color])); // new array
} else if (action.type === 'REMOVE') {
return state.filter(color => color !== action.color); // new array
} else {
return state;
}
}
Run Code Online (Sandbox Code Playgroud)
当action.type未知时,则返回相同的状态对象。因此规则是,reducer 并不严格必须返回一个新的状态对象,但可以返回相同的状态对象。但严格的规则是状态必须是只读的?
我试图理解为什么我似乎无法将参数传递给选择器。
本质上:我有一个存储数字和布尔值的逻辑 - 该数字是我想要选择材料元素的参数 - 我有一个调度操作的按钮:
//on a jobcard - dispatches to the material logic slice, pushing the number into the redux state: materialforJobNumber;
<button className="materialViewer" onClick={() =>{dispatch(materialView(data.jobsessionkey))}}> MATERIAL</button>
Run Code Online (Sandbox Code Playgroud)
它分派到逻辑片:
//logic slice
materialView:(state, action)=>{
console.log("what");
console.log("material view succesfully called", action);
const newState = {...state};
console.log(newState);
newState.materialforJobNumber = action.payload;
newState.showMaterial=true;
return newState
},
Run Code Online (Sandbox Code Playgroud)
//the component that handles displaying the list of material for a job;
import {selectAttachedByJobKey} from "../MaterialCard/MaterialSlice";
const store= useStore();
const foundJN = store.getState().logic.materialforJobNumber;
const selectedJob=store.getState().jobs.find(x=>x.jobsessionkey==foundJN);
const materials = …Run Code Online (Sandbox Code Playgroud) 我正在使用 createSlice() 创建 redux 应用程序,但收到错误:
错误:键“pageName”的切片缩减程序在初始化期间返回未定义。如果传递给reducer的状态未定义,则必须显式返回初始状态。初始状态可能不是未定义的。如果您不想为此减速器设置值,可以使用 null 而不是 undefined。
这是此错误的最小示例。
pageNameSlice.js:
import { createSlice } from "@reduxjs/toolkit";
const pageNameSlice = createSlice({
name: 'pageName',
initalState: "",
// The `reducers` field lets us define reducers and generate associated actions
reducers: {
setPageName: (state, newName) => {
state.pageName = newName
}
}
});
export default pageNameSlice.reducer;
Run Code Online (Sandbox Code Playgroud)
商店.js:
import { configureStore } from '@reduxjs/toolkit';
import pageNameReducer from '../features/pageNameSlice';
export const store = configureStore({
reducer: {
pageName: pageNameReducer
},
});
Run Code Online (Sandbox Code Playgroud) 我有一个自定义钩子,它将在我的 Redux 切片“myTestSlice”中触发两个操作,action1 和 action2,在每个操作后面,我有减速器函数来获取新状态。
const useSetMyObjects = (
actions,
{ object1Name, object1Id, object2Name, object2Id }, // here throws the error cannot read property of undefined when I call the function converted from this custom hook
) => {
const dispatch = useDispatch();
useEffect(() => {
dispatch(actions.action1({ object1Name, object1Id }));
}, [object1Name, object1Id, actions, dispatch]);
useEffect(() => {
dispatch(
actions.action2({
object2Name,
object2Id
}),
);
}, [object2Name, object2Id, actions, dispatch]);
};
export default useSetMyObjects;
Run Code Online (Sandbox Code Playgroud)
我有一个反应组件,我想在数组循环和事件处理程序中使用这个自定义挂钩。因此,我必须将此自定义挂钩转换为函数才能使用它,否则我会收到警告:
React Hook“useSetMyObjects”无法在回调内调用。React Hooks 必须在 React 函数组件或自定义 …
reactjs arrow-functions react-redux react-hooks redux-reducers
你好,我对 React、Redux 和 Saga 还很陌生。所以我有一个场景,我有一个 .jsx 文件,它是视图文件,然后是用于调度的操作文件,我还使用 saga 来更新减速器中的数据。以下是文件结构:
export const getAction = (requestor) => ({
type: GET_ACTION,
data: {
requestor,
},
});
Run Code Online (Sandbox Code Playgroud)
export const Reducer = (currentState = {}, action) => {
const newState = { ...currentState };
switch (action.type) {
case GET_ACTION:
newState.data = action.data;
return newState;
}
};
Run Code Online (Sandbox Code Playgroud)
function* getData(action) {
const { requestor } = action.data;
try {
const data = yield call(callService);
if(success) {
yield put( {type: GET_ACTION, data} );
}
} …Run Code Online (Sandbox Code Playgroud) 我有以下代码:
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import { client } from '../../api/client';
const initialState = {
logBook: [],
status: 'idle',
error: null
};
export const logNewEntry = createAsyncThunk(
'logBook/addNewEntry',
async (logEntry) => {
const response = await client.post('/testPost', logEntry);
console.log('post done');
return response.data;
}
);
const logBookSlice = createSlice({
name: 'logBook',
initialState,
// non async calls
reducers: {},
},
// async calls
extraReducers: {
[logNewEntry.fulfilled] : (state, action) => {
console.log('add to list');
console.log(state);
console.log(action);
state.logBook.push(action.payload);
},
}, …Run Code Online (Sandbox Code Playgroud) 如果是这样,这会导致性能问题吗?
第二
有没有一种方法可以专门调用一个减速器而不调用所有 100 个减速器?
redux-reducers ×10
redux ×8
react-redux ×5
reactjs ×5
javascript ×4
react-hooks ×1
react-native ×1
reducers ×1
redux-saga ×1
redux-thunk ×1