Javascript 如何使用带有钩子的Redux Saga调用API
我正在尝试使用Redux saga中间件来避免异步函数错误,我正在使用React挂钩,我连接了Redux saga并使函数*产生函数,但我不知道为什么它没有读取我的操作来截取它,它给了我相同的错误: 错误:操作必须是普通对象。使用自定义中间件进行异步操作 代码: Store.js Actions.jsJavascript 如何使用带有钩子的Redux Saga调用API,javascript,reactjs,redux,react-redux,react-hooks,Javascript,Reactjs,Redux,React Redux,React Hooks,我正在尝试使用Redux saga中间件来避免异步函数错误,我正在使用React挂钩,我连接了Redux saga并使函数*产生函数,但我不知道为什么它没有读取我的操作来截取它,它给了我相同的错误: 错误:操作必须是普通对象。使用自定义中间件进行异步操作 代码: Store.js Actions.js import axios from 'axios'; import { GetCategories } from './actionTypes' import {GetImages} from '
import axios from 'axios';
import { GetCategories } from './actionTypes'
import {GetImages} from './actionTypes'
export function fetchCategories() {
var url = 'http://localhost:4000/all_categories';
return (dispatch) => {
return axios.get(url).then((res) => {
dispatch({
type: GetCategories,
payload: res.data
})
})
}
}
export function fetchImages(){
var url ='/all_categories';
return(dispatch) => {
return axios.get(url).then((res)=>{
dispatch({
type:GetImages,
payload:res.data
})
})
}
}
Reducers.js
import { GetCategories , GetImages } from "../redux/actions/actionTypes"
const initialState = {
categories: [],
images:[]
};
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case GetCategories:
return {...state, categories: state.categories.concat(action.payload)}
case GetImages:
return{...state,images:action.payload}
default:
return state;
}
};
export default rootReducer;
Saga.js
import {takeEvery,delay} from 'redux-saga/effects'
function* getImagesAsync(){
yield delay(4000);
console.log('api called')
}
export function* watchFetchImages(){
yield takeEvery("GetImages",getImagesAsync);
}
Home.js,我在这里调用redux操作
const HomePage = props => {
useEffect(()=>props.getImages())
console.log(props)
const mapStateToProps = (images) => ({
images
})
const mapDispatchToProps= dispatch =>({
getImages: () => dispatch(fetchImages())
})
export default connect(mapStateToProps,mapDispatchToProps)(HomePage);
Index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { Provider } from "react-redux";
import store from '../src/redux/store';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById('root'));
从“React”导入React;
从“react dom”导入react dom;
从“./App”导入应用程序;
从“react redux”导入{Provider};
从“../src/redux/store”导入存储;
将*作为serviceWorker从“/serviceWorker”导入;
ReactDOM.render(,document.getElementById('root'));
任何人都可以帮我解决这个问题???几周前,我刚刚参与了一个使用redux传奇处理WebSocket的项目,我遇到了一个几乎相同的问题。SageMiddleware确实适用于saga函数,但用于我使用redux thrunk的操作的函数。小例子:
import{
createStore,
applyMiddleware,
组成
}来自“redux”;
从“redux saga”导入createSagaMiddleware;
从“redux thunk”导入thunk;
从“../reducers”导入减速机;
const storeEnhancers=window.uuu REDUX_DEVTOOLS_EXTENSION_uu124;COMPOSE_124;COMPOSE;
const store=createStore(
减速器,
(localStorage['storage'])?JSON.parse(localStorage['storage']):{},
商店增强器(applyMiddleware(sagaMiddleware,thunk))
);代码>几周前,我刚刚参与了一个使用redux传奇处理WebSocket的项目,我遇到了一个几乎相同的问题。SageMiddleware确实适用于saga函数,但用于我使用redux thrunk的操作的函数。小例子:
import{
createStore,
applyMiddleware,
组成
}来自“redux”;
从“redux saga”导入createSagaMiddleware;
从“redux thunk”导入thunk;
从“../reducers”导入减速机;
const storeEnhancers=window.uuu REDUX_DEVTOOLS_EXTENSION_uu124;COMPOSE_124;COMPOSE;
const store=createStore(
减速器,
(localStorage['storage'])?JSON.parse(localStorage['storage']):{},
商店增强器(applyMiddleware(sagaMiddleware,thunk))
);代码>因此我看不到存储设置有任何问题,applyMiddleware
位于正确的位置。我所看到的问题是,在生成器函数中,您可以调用dispatch
,但是这里有几个缺点,请进一步阅读:
相反,您可以调用put
来分派操作。通过创建效果,中间件将处理该问题,并向商店发送适当的操作。因此,一个更好的解决方案是:
相反,我们需要相同的声明性解决方案。创建一个普通的JavaScript对象来指示中间件我们需要分派一些操作,并让中间件执行真正的分派。通过这种方式,我们可以用同样的方式测试发电机的调度:通过检查产生的效果并确保它包含正确的指令
为此,该库提供了另一个函数put,用于创建分派效果
在Saga.js中尝试以下更改:
function* getImagesAsync() {
// here you can call your API
const payloadImages = // result from API response
yield put({type: 'GetImages', payloadImages});
}
export default function* watchFetchImages() {
yield takeEvery('GetImages', getImagesAsync);
}
我希望这有帮助 因此我看不到store
设置有任何问题,applyMiddleware
位于正确的位置。我所看到的问题是,在生成器函数中,您可以调用dispatch
,但是这里有几个缺点,请进一步阅读:
相反,您可以调用put
来分派操作。通过创建效果,中间件将处理该问题,并向商店发送适当的操作。因此,一个更好的解决方案是:
相反,我们需要相同的声明性解决方案。创建一个普通的JavaScript对象来指示中间件我们需要分派一些操作,并让中间件执行真正的分派。通过这种方式,我们可以用同样的方式测试发电机的调度:通过检查产生的效果并确保它包含正确的指令
为此,该库提供了另一个函数put,用于创建分派效果
在Saga.js中尝试以下更改:
function* getImagesAsync() {
// here you can call your API
const payloadImages = // result from API response
yield put({type: 'GetImages', payloadImages});
}
export default function* watchFetchImages() {
yield takeEvery('GetImages', getImagesAsync);
}
我希望这有帮助 将存储区
传递给它时,如何使用
?你能不能也分享一下index.js
?谢谢@norbitrial我添加了index.js,如果您有任何其他意见,除了我的问题,请通知我的,我还不熟悉redux和hooksInSaga.js
您是否也导出了watchFetchImages
函数,还是示例中缺少了该函数?@norbitrial它在示例中被导出了我是否需要将另一个函数也导出到getImagesAsync中?错误是真的。我使用Redux Thrunk在操作中创建函数。将存储区
传递给它时,如何使用
?你能不能也分享一下index.js
?谢谢@norbitrial我添加了index.js,如果您有任何其他意见,除了我的问题,请通知我的,我还不熟悉redux和hooksInSaga.js
您是否也导出了watchFetchImages
函数,还是示例中缺少了该函数?@norbitrial它在示例中被导出了我是否需要将另一个函数也导出到getImagesAsync中?错误是真的。我使用Redux Thrunk在操作中创建函数。谢谢,但我需要使用Sagas OnlyTanks,但我需要使用Sagas Only我尝试过做这个仍然相同的错误,我尝试在reducer中添加另一个操作案例来处理saga中间件仍然相同的错误,我认为错误来自takeEvery函数不识别动作“GetImages”,所以它没有拦截它,仍然不知道如何修复我的新代码:Saga.jsfunctio