gpt4 book ai didi

reactjs - 无法读取 Redux thunk 操作上未定义的属性 'then'

转载 作者:行者123 更新时间:2023-12-03 14:12:35 26 4
gpt4 key购买 nike

我是 React、Redux 和 Thunk 的新手,并且一直在关注有关该主题的教程,最近 Building Applications with React and Redux in ES6在 Pluralsight 上。我已将本教程从 ES6 转换为 Typescript 3,并将 React v3 转换为 React v4。

我遇到了很多可以按照此模式解决的问题(尤其是与路由相关的任何问题),但我遇到了一个无法解决的问题。来自各种来源公司Cannot read property '.then' of undefined when testing async action creators with redux and react听起来我不能在返回 void 的函数上使用 .then() 函数,但它是一个异步函数(应该)返回一个 promise ,但智能感知却另有说法。代码如下。

saveCourse = (event: any) => {
event.preventDefault();
this.props.actions.saveCourse(this.state.course)
.then(this.setState({ fireRedirect: true }));
}

上面的代码位于我的组件上,props.actions 通过 mapStateToProps 连接到 redux 存储,并且在单击按钮时调用此函数。上面这个函数的 .then() 出现了错误。该函数调用下面的操作

export const saveCourse = (course: Course) => {
return (dispatch: any, getState: any) => {
dispatch(beginAjaxCall());
courseApi.saveCourse(course).then((savedCourse: Course) => {
course.id ? dispatch(updateCourseSuccess(savedCourse)) :
dispatch(createCourseSuccess(savedCourse));
}).catch(error => {
throw (error);
});
}
}

上面的操作是异步调用,这里的 .then() 没有错误,但 VS Code 说整个 saveCourse 函数返回 void。

从教程来看,确实没有任何差异可以产生影响(箭头函数而不是常规函数等...),所以我想知道我缺少的版本之间是否存在模糊的变化,但不知道在哪里看看,可能会遗漏一些基本的东西。谁能明白为什么我不能在 saveCourse() 函数上执行 .then() 吗?

如果您需要更多信息,请告诉我。

编辑:courseApi 只是一个模拟 api,代码如下。

import delay from './delay';

const courses = [
{
id: "react-flux-building-applications",
title: "Building Applications in React and Flux",
watchHref: "http://www.pluralsight.com/courses/react-flux-building-applications",
authorId: "cory-house",
length: "5:08",
category: "JavaScript"
},
{
id: "clean-code",
title: "Clean Code: Writing Code for Humans",
watchHref: "http://www.pluralsight.com/courses/writing-clean-code-humans",
authorId: "cory-house",
length: "3:10",
category: "Software Practices"
},
{
id: "architecture",
title: "Architecting Applications for the Real World",
watchHref: "http://www.pluralsight.com/courses/architecting-applications-dotnet",
authorId: "cory-house",
length: "2:52",
category: "Software Architecture"
},
{
id: "career-reboot-for-developer-mind",
title: "Becoming an Outlier: Reprogramming the Developer Mind",
watchHref: "http://www.pluralsight.com/courses/career-reboot-for-developer-mind",
authorId: "cory-house",
length: "2:30",
category: "Career"
},
{
id: "web-components-shadow-dom",
title: "Web Component Fundamentals",
watchHref: "http://www.pluralsight.com/courses/web-components-shadow-dom",
authorId: "cory-house",
length: "5:10",
category: "HTML5"
}
];

function replaceAll(str: any, find: any, replace: any) {
return str.replace(new RegExp(find, 'g'), replace);
}

//This would be performed on the server in a real app. Just stubbing in.
const generateId = (course: any) => {
return replaceAll(course.title, ' ', '-');
};

class CourseApi {
static getAllCourses() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(Object.assign([], courses));
}, delay);
});
}

static saveCourse(course: any) {
course = Object.assign({}, course); // to avoid manipulating object passed in.
return new Promise((resolve, reject) => {
setTimeout(() => {
// Simulate server-side validation
const minCourseTitleLength = 1;
if (course.title.length < minCourseTitleLength) {
reject(`Title must be at least ${minCourseTitleLength} characters.`);
}

if (course.id) {
const existingCourseIndex = courses.findIndex(a => a.id == course.id);
courses.splice(existingCourseIndex, 1, course);
} else {
//Just simulating creation here.
//The server would generate ids and watchHref's for new courses in a real app.
//Cloning so copy returned is passed by value rather than by reference.
course.id = generateId(course);
course.watchHref = `http://www.pluralsight.com/courses/${course.id}`;
courses.push(course);
}

resolve(course);
}, delay);
});
}

static deleteCourse(courseId: any) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const indexOfCourseToDelete = courses.findIndex(course =>
course.id == courseId
);
courses.splice(indexOfCourseToDelete, 1);
resolve();
}, delay);
});
}
}

export default CourseApi;

最佳答案

您遇到的问题是您没有返回 Action Creator 中的 promise 。

在这里查看 redux-thunk 的示例:

https://github.com/reduxjs/redux-thunk

function makeASandwichWithSecretSauce(forPerson) {

// Invert control!
// Return a function that accepts `dispatch` so we can dispatch later.
// Thunk middleware knows how to turn thunk async actions into actions.

return function (dispatch) {
return fetchSecretSauce().then(
sauce => dispatch(makeASandwich(forPerson, sauce)),
error => dispatch(apologize('The Sandwich Shop', forPerson, error))
);
};
}

他们正在返回由 fetchSecretSauce 生成的 promise 。

您需要在示例中类似地返回 promise :

export const saveCourse = (course: Course) => {
return (dispatch: any, getState: any) => {
dispatch(beginAjaxCall());
return courseApi.saveCourse(course).then((savedCourse: Course) => {
course.id ? dispatch(updateCourseSuccess(savedCourse)) :
dispatch(createCourseSuccess(savedCourse));
}).catch(error => {
throw (error);
});
}
}

关于reactjs - 无法读取 Redux thunk 操作上未定义的属性 'then',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51981388/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com