React Redux Saga:操作必须是普通对象。使用自定义中间件进行异步操作
React Redux Saga: Actions must be plain objects. Use custom middleware for async actions
我在这上面花了很多时间,仍然不知道发生了什么,我正在开发一个 React 应用程序来向 api 发送 post 请求,每次我单击添加按钮以调度操作,我收到错误消息“操作必须是普通对象”
这里是actions/index.js
import { createAction } from "redux-actions";
import * as actions from "../actionTypes
export const CreateUserRequest = createAction(actions.CREATE_USER_REQUEST);
export const CreateUserSuccess = createAction(actions.CREATE_USER_SUCCESS);
export const CreateUserError = createAction(actions.CREATE_USER_ERROR);
actionTypes/index.js
export const CREATE_USER_REQUEST = "CREATE_USER_REQUEST";
export const CREATE_USER_SUCCESS = "CREATE_USER_SUCCESS";
export const CREATE_USER_ERROR = "CREATE_USER_ERROR";
reducers/createUser.js
import * as actions from "../actionTypes";
const initialState = {
isLoading: false,
isSuccess: false,
isError: false
};
const createUser = (state = initialState, action) => {
switch (action.type) {
case actions.CREATE_USER_REQUEST:
return {
...state,
isLoading: true,
isSuccess: false,
isError: false
};
case actions.CREATE_USER_SUCCESS:
return {
...state,
isLoading: false,
isSuccess: true,
isError: false,
result: action.payload,
};
case actions.CREATE_USER_ERROR:
return {
...state,
isLoading: false,
isSuccess: false,
isError: true,
result: action.payload,
};
default:
return state;
}
};
export default createUser;
reducers/index.js
import { combineReducers } from "redux";
import CreateUserReducer from './createUser';
const rootReducer = combineReducers({
CreateUserStatus:CreateUserReducer,
//logout:logout,
})
export default rootReducer
saga/createUser.js
import { call, put, takeLatest } from "redux-saga/effects";
import { CreateUserSuccess, CreateUserError, CreateUserRequest } from '../actions/index';
import axiosCall from "../../services";
import * as actions from "../actionTypes"
export function* createUserRequest(action) {
try {
const response = yield call(
axiosCall,
"POST",
'/api/createUser',
action.payload,
);
if (response) {
yield put(CreateUserSuccess({ response : response.data}));
} else {
yield put(CreateUserError({ error: "Invalid details" }));
}
} catch (error) {
console.log('errrrrrrrrr::',error)
yield put(CreateUserError({ error: "Invalid detailssssssss" }));
}
yield takeLatest(actions.CREATE__USER_REQUEST, CreateUserRequest);
}
saga/index.js
import { fork, all } from "redux-saga/effects";
import {createUserRequest} from './createUser';
function* rootSaga() {
{
yield all([
fork(createUserRequest),
]);
}
}
export default rootSaga;
store.js
import { createStore, applyMiddleware } from "redux";
import createSagaMiddleware from "redux-saga";
import rootReducer from "../reducers";
import rootSaga from "../saga/index";
import { createLogger } from "redux-logger";
const middleWares = [];
import { composeWithDevTools } from "redux-devtools-extension";
const logger = createLogger({
predicate: () => process.env.NODE_ENV === 'development',
collapsed: true
});
const sagaMiddleware = createSagaMiddleware();
middleWares.push(sagaMiddleware);
middleWares.push(logger);
const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(...middleWares)));
sagaMiddleware.run(rootSaga);
export default store;
组件createUser.js
import React, { useState} from 'react';
import { useDispatch } from "react-redux"
import {
Container,
} from '../../components';
import { createUserRequest } from '../../redux/actions';
const createUser = () => {
const dispatch = useDispatch()
const [newuser,setNewuser] = useState({
first_name : 'Jon',
last_name : 'Doe',
email : 'jondoe@gmail.com',
phone_number: '+91234455',
status:0
})
const handleChange = (e) =>{
setNewuser({...newuser,[e.target.name] : e.target.value});
}
//Add new user
const add_user = ()=>{
dispatch(createUserRequest(newuser));
}
return (
<Container>
<form>
<input type="text" className="form-control" name="first_name" onChange={handleChange}/>
<input type="text" className="form-control" name="last_name" onChange={handleChange}/>
<input type="text" className="form-control" name="email" onChange={handleChange}/>
<input type="text" className="form-control" name="phone_number" onChange={handleChange}/>
<input type="button" className="form-control" onClick={()=>{add_user()}}/>
</form>
</Container>
)
}
export default createUsers;
我现在收到错误信息
Uncaught TypeError: Object(...) is not a function
at add_user (createusers.js?2170:55)
at onClick (createusers.js?2170:82)
at HTMLUnknownElement.callCallback (react-dom.development.js?61bb:188)
at Object.invokeGuardedCallbackDev (react-dom.development.js?61bb:237)
at invokeGuardedCallback (react-dom.development.js?61bb:292)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js?61bb:306)
at executeDispatch (react-dom.development.js?61bb:389)
at executeDispatchesInOrder (react-dom.development.js?61bb:414)
at executeDispatchesAndRelease (react-dom.development.js?61bb:3278)
at executeDispatchesAndReleaseTopLevel (react-dom.development.js?61bb:3287)
指向这一行
dispatch(createUserRequest(newuser));
问题
您似乎正在尝试调度您的 saga 函数,createUserRequest
。
import { createUserRequest } from '../../redux/saga/createUser';
...
//Add new user
const add_user = () => {
dispatch(createUserRequest({ newuser: newuser }));
}
解决方案
您需要创建一个接受“新用户”负载的操作。也许你打算使用 CreateUserRequest
.
import { createAction } from "redux-actions";
import * as actions from "../actionTypes;
export const CreateUserRequest = createAction(actions.CREATE_USER_REQUEST); // <-- ***
export const CreateUserSuccess = createAction(actions.CREATE_USER_SUCCESS);
export const CreateUserError = createAction(actions.CREATE_USER_ERROR);
因此在 createUser
组件中。
import React, { useState } from 'react';
import { useDispatch } from "react-redux";
import { Container } from '../../components';
import { CreateUserRequest } from '../../redux/actions';
const createUser = () => {
const dispatch = useDispatch()
const [newuser, setNewuser] = useState({
first_name : '',
last_name : '',
email : '',
phone_number: '',
status:0
});
...
//Add new user
const add_user = () => {
dispatch(CreateUserRequest({ newuser })); // <-- dispatch action payload
}
return (
...
)
}
我在这上面花了很多时间,仍然不知道发生了什么,我正在开发一个 React 应用程序来向 api 发送 post 请求,每次我单击添加按钮以调度操作,我收到错误消息“操作必须是普通对象”
这里是actions/index.js
import { createAction } from "redux-actions";
import * as actions from "../actionTypes
export const CreateUserRequest = createAction(actions.CREATE_USER_REQUEST);
export const CreateUserSuccess = createAction(actions.CREATE_USER_SUCCESS);
export const CreateUserError = createAction(actions.CREATE_USER_ERROR);
actionTypes/index.js
export const CREATE_USER_REQUEST = "CREATE_USER_REQUEST";
export const CREATE_USER_SUCCESS = "CREATE_USER_SUCCESS";
export const CREATE_USER_ERROR = "CREATE_USER_ERROR";
reducers/createUser.js
import * as actions from "../actionTypes";
const initialState = {
isLoading: false,
isSuccess: false,
isError: false
};
const createUser = (state = initialState, action) => {
switch (action.type) {
case actions.CREATE_USER_REQUEST:
return {
...state,
isLoading: true,
isSuccess: false,
isError: false
};
case actions.CREATE_USER_SUCCESS:
return {
...state,
isLoading: false,
isSuccess: true,
isError: false,
result: action.payload,
};
case actions.CREATE_USER_ERROR:
return {
...state,
isLoading: false,
isSuccess: false,
isError: true,
result: action.payload,
};
default:
return state;
}
};
export default createUser;
reducers/index.js
import { combineReducers } from "redux";
import CreateUserReducer from './createUser';
const rootReducer = combineReducers({
CreateUserStatus:CreateUserReducer,
//logout:logout,
})
export default rootReducer
saga/createUser.js
import { call, put, takeLatest } from "redux-saga/effects";
import { CreateUserSuccess, CreateUserError, CreateUserRequest } from '../actions/index';
import axiosCall from "../../services";
import * as actions from "../actionTypes"
export function* createUserRequest(action) {
try {
const response = yield call(
axiosCall,
"POST",
'/api/createUser',
action.payload,
);
if (response) {
yield put(CreateUserSuccess({ response : response.data}));
} else {
yield put(CreateUserError({ error: "Invalid details" }));
}
} catch (error) {
console.log('errrrrrrrrr::',error)
yield put(CreateUserError({ error: "Invalid detailssssssss" }));
}
yield takeLatest(actions.CREATE__USER_REQUEST, CreateUserRequest);
}
saga/index.js
import { fork, all } from "redux-saga/effects";
import {createUserRequest} from './createUser';
function* rootSaga() {
{
yield all([
fork(createUserRequest),
]);
}
}
export default rootSaga;
store.js
import { createStore, applyMiddleware } from "redux";
import createSagaMiddleware from "redux-saga";
import rootReducer from "../reducers";
import rootSaga from "../saga/index";
import { createLogger } from "redux-logger";
const middleWares = [];
import { composeWithDevTools } from "redux-devtools-extension";
const logger = createLogger({
predicate: () => process.env.NODE_ENV === 'development',
collapsed: true
});
const sagaMiddleware = createSagaMiddleware();
middleWares.push(sagaMiddleware);
middleWares.push(logger);
const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(...middleWares)));
sagaMiddleware.run(rootSaga);
export default store;
组件createUser.js
import React, { useState} from 'react';
import { useDispatch } from "react-redux"
import {
Container,
} from '../../components';
import { createUserRequest } from '../../redux/actions';
const createUser = () => {
const dispatch = useDispatch()
const [newuser,setNewuser] = useState({
first_name : 'Jon',
last_name : 'Doe',
email : 'jondoe@gmail.com',
phone_number: '+91234455',
status:0
})
const handleChange = (e) =>{
setNewuser({...newuser,[e.target.name] : e.target.value});
}
//Add new user
const add_user = ()=>{
dispatch(createUserRequest(newuser));
}
return (
<Container>
<form>
<input type="text" className="form-control" name="first_name" onChange={handleChange}/>
<input type="text" className="form-control" name="last_name" onChange={handleChange}/>
<input type="text" className="form-control" name="email" onChange={handleChange}/>
<input type="text" className="form-control" name="phone_number" onChange={handleChange}/>
<input type="button" className="form-control" onClick={()=>{add_user()}}/>
</form>
</Container>
)
}
export default createUsers;
我现在收到错误信息
Uncaught TypeError: Object(...) is not a function
at add_user (createusers.js?2170:55)
at onClick (createusers.js?2170:82)
at HTMLUnknownElement.callCallback (react-dom.development.js?61bb:188)
at Object.invokeGuardedCallbackDev (react-dom.development.js?61bb:237)
at invokeGuardedCallback (react-dom.development.js?61bb:292)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js?61bb:306)
at executeDispatch (react-dom.development.js?61bb:389)
at executeDispatchesInOrder (react-dom.development.js?61bb:414)
at executeDispatchesAndRelease (react-dom.development.js?61bb:3278)
at executeDispatchesAndReleaseTopLevel (react-dom.development.js?61bb:3287)
指向这一行
dispatch(createUserRequest(newuser));
问题
您似乎正在尝试调度您的 saga 函数,createUserRequest
。
import { createUserRequest } from '../../redux/saga/createUser';
...
//Add new user
const add_user = () => {
dispatch(createUserRequest({ newuser: newuser }));
}
解决方案
您需要创建一个接受“新用户”负载的操作。也许你打算使用 CreateUserRequest
.
import { createAction } from "redux-actions";
import * as actions from "../actionTypes;
export const CreateUserRequest = createAction(actions.CREATE_USER_REQUEST); // <-- ***
export const CreateUserSuccess = createAction(actions.CREATE_USER_SUCCESS);
export const CreateUserError = createAction(actions.CREATE_USER_ERROR);
因此在 createUser
组件中。
import React, { useState } from 'react';
import { useDispatch } from "react-redux";
import { Container } from '../../components';
import { CreateUserRequest } from '../../redux/actions';
const createUser = () => {
const dispatch = useDispatch()
const [newuser, setNewuser] = useState({
first_name : '',
last_name : '',
email : '',
phone_number: '',
status:0
});
...
//Add new user
const add_user = () => {
dispatch(CreateUserRequest({ newuser })); // <-- dispatch action payload
}
return (
...
)
}