Reactjs 如何在React和redux应用程序中使用redux pack将承诺链接到API调用的返回?
我得到了一个错误Reactjs 如何在React和redux应用程序中使用redux pack将承诺链接到API调用的返回?,reactjs,promise,react-redux,Reactjs,Promise,React Redux,我得到了一个错误。那么()在尝试编写React应用程序testw/jest/enzyme时不是一个函数。我不认为测试代码是问题所在,但作为参考,我遵循这一点 下面是引发错误的代码: return store.dispatch(actions.fetchFiles()).then(() => { expect(store.getActions()).toEqual(expectedActions) }); 我的客户的代码库使用redux pack和一些我不熟悉的约定,我很难理解实际承诺
。那么()在尝试编写React应用程序testw/jest/enzyme时不是一个函数。我不认为测试代码是问题所在,但作为参考,我遵循这一点
下面是引发错误的代码:
return store.dispatch(actions.fetchFiles()).then(() => {
expect(store.getActions()).toEqual(expectedActions)
});
我的客户的代码库使用redux pack和一些我不熟悉的约定,我很难理解实际承诺在哪里执行,因此在从我的测试代码调用“then”函数时如何链接它,如上面发布的redux示例链接所示
我试着做了一些调试日志记录和一些语法变体,例如,我尝试调用。然后直接调用actions.fetchFiles()
,因为我觉得实际上是调用返回了承诺,但它不起作用。我在所有这些代码中都有点迷失了方向,并质疑承诺到底在哪里执行/返回
该守则的基本结构如下:
一个已连接的容器组件,它从API获取文件列表,然后进行分派
实际页面运行良好,但我的测试尝试(如上面提到的Redux文章)失败了
以下是我认为相关的代码块:
容器组件
componentDidMount() {
const { actions } = this.props;
actions.fetchUpload();
}
const mapStateToProps = state => ({
...state.upload,
});
const mapDispatchToProps = dispatch => ({
actions: bindActionCreators({
...uploadActions,
}, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(UploadContainer);
actions.js
import api from '../../core/api';
export const FETCH_FILES = 'upload/fetch-files';
const actions = {
fetchFiles: () => ({
type: FETCH_FILES,
promise: api.upload.getFiles()
})
};
actions.fetchUpload = () => (dispatch) => {
dispatch(actions.fetchFiles());
};
export default actions;
reducer.js
import { handle } from 'redux-pack';
import { FETCH_FILES } from './actions';
const initialState = {
files: []
};
export default (state = initialState, action) => {
switch (action.type) {
case FETCH_FILES:
return handle(state, action, { // this is redux-pack syntax
success: (s, a) => ({ ...s, files: a.payload.files })
});
default:
return state;
}
};
upload.js(api.upload.getFiles)
api.js-使用Axios
import Axios from 'axios';
import { SubmissionError } from 'redux-form';
import queryString from 'query-string';
import upload from './upload';
const axios = Axios.create({
baseURL: '/api/',
withCredentials: true,
paramsSerializer: params => queryString.stringify(params),
});
class HttpError extends Error {
constructor(status, error, errors = {}) {
super(`Http Error: ${status}`);
this.status = status;
this.error = error;
this.errors = errors;
}
getReduxFormError = defaultError => new SubmissionError({
_error: this.error || defaultError,
...this.errors,
});
}
const handleUnauth = (method, url, options) => (err) => {
const { status } = err.response;
if (status === 401) {
return axios.get('/users/refresh')
.then(() => method(url, options))
.catch(() => Promise.reject(err));
}
return Promise.reject(err);
};
const handleHttpError = (err) => {
const { status, data: { message = {} } } = err.response;
if (typeof message === 'string') {
return Promise.reject(new HttpError(status, message));
}
return Promise.reject(new HttpError(status, null, message));
};
const http = {
get: (url, options) => axios.get(url, options)
.then(response => response.data)
.catch(handleUnauth(axios.get, url, options))
.catch(handleHttpError),
post: (url, data, options) => axios.post(url, data, options)
.then(response => response.data)
.catch(handleUnauth(axios.post, url, options))
.catch(handleHttpError),
patch: (url, data, options) => axios.patch(url, data, options)
.then(response => response.data)
.catch(handleUnauth(axios.patch, url, options))
.catch(handleHttpError),
delete: (url, options) => axios.delete(url, options)
.then(response => response.data)
.catch(handleUnauth(axios.delete, url, options))
.catch(handleHttpError),
};
export default {
upload: upload(http)
};
我希望测试能够通过,因为返回的对象应该与预期的操作匹配,但它会出错。以下是完整的信息:
FAIL src/modules/upload/upload.test.js
Upload module actions › Returns an array of files when calling actions.fetchFiles
TypeError: store.dispatch(...).then is not a function
43 | // );
44 |
> 45 | return store.dispatch(actions.fetchFiles()).then(() => {
|
46 | expect(store.getActions()).toEqual(expectedActions);
47 | });
48 | });
at Object.then (src/modules/upload/upload.test.js:45:52)
承诺何时/何地返回,我如何链接a。然后像上面链接的Redux测试示例一样运行?据我所知,您想要调度异步操作,请使用Redux thunk
进行此操作。如果查看文档,存储。调度返回调度的操作:。在您的例子中,fetchFiles
返回一个带有promise
属性的对象,因此您可以通过执行类似于store.dispatch(actions.fetchFiles()).promise的操作来链接它。然后(()=>{})
@PaoloMoretti,我尝试了这个操作,但得到的错误是.promise不是函数<代码>类型错误:store.dispatch(…).promise不是函数
`>45 |返回store.dispatch(actions.fetchFiles()).promise()。然后(()=>{`@RohitKashyap,谢谢你的建议。应用程序已经在生产中使用redux-thunk
进行异步操作,并且在那里工作得很好;但是,我的测试代码失败了,那就是使用redux-mock-store
来测试redux异步操作。也就是说,我仍然认为我无法链接我的。然后()
返回承诺。@J2Gpromise
确实不是一个函数,你应该删除promise
和之间的函数调用,然后。据我所知,你想要调度async
操作,使用redux thunk
来实现。如果你查看文档,store.dispatch
returns调度的操作:。在您的示例中,fetchFiles
返回一个具有promise
属性的对象,因此您可以通过执行类似于store.dispatch(actions.fetchFiles()).promise的操作来链接它。然后(()=>{})
@PaoloMoretti,我试过了,但得到的错误是.promise不是函数。TypeError:store.dispatch(…).promise不是函数
`>45 | return store.dispatch(actions.fetchFiles()).promise()。然后(()=>{`@RohitKashyap,谢谢你的建议。应用程序已经在生产中使用redux-thunk
进行异步操作,并且在那里工作得很好;但是,我的测试代码失败了,那就是使用redux-mock-store
来测试redux异步操作。也就是说,我仍然认为我无法链接我的。然后()
返回承诺。@J2Gpromise
确实不是一个函数,您应该删除promise
和之间的函数调用,然后
。
FAIL src/modules/upload/upload.test.js
Upload module actions › Returns an array of files when calling actions.fetchFiles
TypeError: store.dispatch(...).then is not a function
43 | // );
44 |
> 45 | return store.dispatch(actions.fetchFiles()).then(() => {
|
46 | expect(store.getActions()).toEqual(expectedActions);
47 | });
48 | });
at Object.then (src/modules/upload/upload.test.js:45:52)