reactjs - 动作必须是普通对象。使用自定义中间件进行异步操作 Saga thunk 到目前为止我的商店中确实有
问题描述
问题是:
我试图在我的反应应用程序中使用 redux-saga,但我仍然有这个错误:动作必须是普通对象。使用自定义中间件进行异步操作。代码看起来是正确的,但不知道为什么会出现这个错误。我会很高兴所有的帮助。我与它战斗了大约两天,但仍然没有解决方案。我试图查找,但我仍然有这个错误。
action...
import { GET_DISTRICTS} from '../../constants';
const getAdres = async (url) => {
let response = await fetch(url);
let data = await response.json();
let list = [];
data.AdresList.Adresler.Adres.forEach((item) => {
console.info(item);
list.push({
label: item.ADI,
value: item.ID
});
});
return list;
};
export const actions = {
handleGetDistrictsData: async () => {
let districts = await getAdres(`url is here`);
return {
type: GET_DISTRICTS,
payload: districts
};
},
reducer...
import { GET_DISTRICTS } from '../../constants';
export const initialState = {
districts: [],
quarters: [],
streets: [],
doors: [],
districtSelected: false,
districtSelectedID: null,
quarterSelected: false,
quarterSelectedID: null,
streetSelected: false,
streetSelectedID: null,
doorSelected: false,
doorSelectedID: null
};
export default (state = initialState, action) => {
switch (action.type) {
case GET_DISTRICTS:
return {
...state,
districts: action.payload
};
default:
return state;
}
};
component...
import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { actions as addressActions } from '../../../../redux/actions/address';
import Select from 'react-select';
const Districts = (props) => {
let [ fetchedData, setFetchedData ] = useState(false);
useEffect(() => {
props.handleGetDistrictsData();
setFetchedData(true);
});
return (
<React.Fragment>
<Select
name='adresSelect'
options={props.address.districts}
onChange={props.handleDistrictChange}
placeholder='Please Select'
/>
</React.Fragment>
);
};
const mapStateToProps = (state) => ({
address: state.address
});
const mapDispatchToProps = function(dispatch) {
return bindActionCreators({ ...addressActions }, dispatch);
};
export default connect(mapStateToProps, mapDispatchToProps)(Districts);
-------------
import React from 'react';
import Districts from './Districts';
const AddressSearchWidget = (props) => {
return (
<React.Fragment>
<Districts />
</React.Fragment>
);
};
export default AddressSearchWidget
store...
import { applyMiddleware, combineReducers, compose, createStore } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootSaga from './sagas/index';
import * as reducers from './';
export function initStore() {
const composeEnhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const rootReducer = combineReducers(reducers);
const sagaMiddleware = createSagaMiddleware();
const store = createStore(rootReducer, composeEnhancer(applyMiddleware(sagaMiddleware)));
// Run sagas
sagaMiddleware.run(rootSaga);
return store;
}
解决方案
handleGetDistrictsData
返回一个承诺(所有异步函数都返回承诺)。你不能在普通的 redux saga 中发送 promise,redux-saga 不会改变这一点。相反,调度一个正常的动作,并让该动作运行一个传奇。然后 saga 可以执行异步操作,并在完成后调度另一个操作。reducer 只监听第二个动作。
// Actions:
export const getDistrictsData = () => ({
type: GET_DISTRICTS,
})
export const districtsDataSuccess = (districts) => ({
type: DISTRICTS_DATA_SUCCESS,
payload: districts
})
// Sagas:
export function* watchGetDistricts () {
takeEvery(GET_DISTRICTS, getDistricts);
}
function* getDistricts() {
let response = yield fetch(url);
let data = yield response.json();
let list = [];
data.AdresList.Adresler.Adres.forEach((item) => {
console.info(item);
list.push({
label: item.ADI,
value: item.ID
});
});
yield put(districtsDataSuccess(list));
}
// reducer:
export default (state = initialState, action) => {
switch (action.type) {
case DISTRICTS_DATA_SUCCESS:
return {
...state,
districts: action.payload
};
default:
return state;
}
};
推荐阅读
- node.js - 续集同一类的两个关系
- python - How to install Polynote on Windows?
- php - Laravel Cashier 10 - 条纹支付元素为空
- node.js - Feathers services usage and eslint
- python - django admin send back to homepage
- reactjs - Specify Next.js build directory in build command?
- html - 如何让固定元素在 100% 的 body 之后滚动?
- watchkit - 为什么我的 Xcode 11.2.1 (11B500)“Watch App”模板失败?
- javascript - 如何使用 jquery 从 HTML 中动态创建的表(带按钮)中获取某个表单输入的值?
- tensorflow - 如何将 keras.utils.Sequence 与多个文件一起使用