reactjs - redux-saga: Actions must be plain objects
问题描述
I have a problem with my saga and I don't have any idea what is wrong. Im getting an error like Actions must be plain objects. Use custom middleware for async actions while using react redux. Here is my code.
container/index.js
class AppContainer extends Component {
componentDidMount() {
const { actions: { onFetchPhoto } } = this.props;
onFetchPhoto();
}
render() {
return (
<App />
);
}
}
const mapDispatchToProps = (dispatch) => ({
actions: {
onFetchPhoto: () => dispatch(fetchPhoto())
}
})
export default connect(null, mapDispatchToProps)(AppContainer);
actions/index.js
export const FETCH_PHOTO_REQUEST = "FETCH_PHOTO_REQUEST";
export const FETCH_PHOTO_SUCCESS = "FETCH_PHOTO_SUCCESS";
export const FETCH_PHOTO_FAILURE = "FETCH_PHOTO_FAILURE";
export function fetchPhoto(payload) {
return {
type: FETCH_PHOTO_REQUEST
}
}
export function fetchPhotoSuccess(payload) {
return {
type: FETCH_PHOTO_SUCCESS,
payload
}
}
export function fetchPhotoFailure(error) {
return {
type: FETCH_PHOTO_SUCCESS,
payload: {
error
}
}
}
sagas/index.js
function* fetchRandomPhoto() {
//yield put(fetchPhoto());
const {
response,
error
} = yield call(fetchRandomPhotoApi)
if (response) {
yield put(fetchPhotoSuccess(response))
} else {
yield put(fetchPhotoFailure(error))
}
}
function* watchLoadRandomPhoto() {
try {
while (true) {
yield takeLatest(FETCH_PHOTO_REQUEST, fetchRandomPhoto);
}
}
catch(error) {
console.error("error in saga", error)
}
}
export default function* rootSaga() {
yield fork(watchLoadRandomPhoto)
}
services/index.js
import axios from 'axios';
import {
URL,
PUBLIC_KEY
} from 'src/constants/config';
import {
schema,
normalize
} from 'normalizr'
export function fetchRandomPhotoApi() {
return axios({
url: `${URL}/photos/random`,
timeout: 10000,
method: 'get',
headers: {
'Autorization': `Client-ID ${PUBLIC_KEY}`
},
responseType: 'json'
})
.then((response) => {
const { data } = response.data;
console.log("d");
if (data) {
return ({
response: {
id: data.id,
url: data.urls.full,
title: data.location.title
}
})
}
})
.catch(error => error)
}
store/configureStore.js
import rootReducer from 'src/reducers/root';
import rootSaga from 'src/sagas';
export default function configureStore() {
const logger = createLogger();
const sagaMiddleware = createSagaMiddleware();
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
rootReducer,
compose(
applyMiddleware(
sagaMiddleware,
logger,
composeEnhancers
),
)
);
sagaMiddleware.run(rootSaga);
return store;
}
I waste 2 day to fix this problem, but no result. Chrome showed me this error:
解决方案
The source of your problem lies within fetchRandomPhotoApi function. Without knowing what that looks like I can't say for certain but if it is for example a function that return a promise you should be calling like
const { response, error } = yield call(fetchRandomPhotoApi)
Notice the lack of brackets in the call.
Update
From your edit I can now see that the promise is not resolved in your api call. You want that function to return an object instead of the actual promise to pass on to your actions. Something on the lines of:
axios({...etc}).then(response => response).catch(error => error)
推荐阅读
- powershell - 需要 powershell 命令将多个“团队呼叫队列”数据导出到 .csv 文件
- ubuntu-18.04 - 在ubuntu的shell脚本中以非交互方式设置新用户的密码
- compilation - 在 C++ Builder 中隐藏控制台窗口
- vba - MS 访问 VBA 更新创建重复条目
- cmake - 为什么断言 CPACK_DEBIAN_DEBUGINFO_PACKAGE 不会生成 .ddeb 文件?
- python - 使用状态机在 pygame 中获得连续运动
- typescript - 如何在 TypeScript 中定义具有已定义属性和索引“后备”的类型
- javascript - 用道具反应问题:TypeError:无法读取未定义的属性“xxxx”
- amazon-web-services - VPC 中的 Lambda 无法访问 DigitalOcean S3 资源
- javascript - 使用 React 交替样式化深度嵌套列表中的项目