我创建了一个 react-redux 应用程序。目前它所做的是从服务器(api)加载类(class),并将它们显示到类(class)组件。这完美地工作。我正在尝试添加一个功能,您可以在其中通过将类(class)发布到服务器来创建类(class),然后服务器将返回一个成功对象。但是,当我发布到服务器时,出现以下错误(见下文)。我认为这是由于我的 connect 语句在监听负载类(class)操作。很明显,它认为它应该得到一个列表,而不是一个成功对象。我已经尝试了一些方法来收听类(class)和成功响应,但是为了节省您阅读我所做的所有奇怪事情的时间,我无法让它发挥作用。有谁知道如何解决这个问题?
错误
TypeError: this.props.courses.map is not a function
onSave(){
// this.props.createCourse(this.state.course);
this.props.actions.createCourse(this.state.course);
}
render() {
return (
<div>
<div className="row">
<h2>Couses</h2>
{this.props.courses.map(this.courseRow)}
<input
type="text"
onChange={this.onTitleChange}
value={this.state.course.title} />
<input
type="submit"
onClick={this.onSave}
value="Save" />
</div>
</div>
);
}
}
// Error occurs here
function mapStateToProps(state, ownProps) {
return {
courses: state.courses
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(courseActions, dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(Course);
export function loadCourse(response) {
return {
type: REQUEST_POSTS,
response
};
}
export function fetchCourses() {
return dispatch => {
return fetch('http://localhost:3000/api/test')
.then(data => data.json())
.then(data => {
dispatch(loadCourse(data));
}).catch(error => {
throw (error);
});
};
}
export function createCourse(response) {
return dispatch => {
return fetch('http://localhost:3000/api/json', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
response: response
})
})
.then(data => data.json())
.then(data => {
dispatch(loadCourse(data));
}).catch(error => {
throw (error);
});
};
}
export default function courseReducer(state = [], action) {
switch (action.type) {
case 'REQUEST_POSTS':
return action.response;
default:
return state;
}
}
router.get('/test', function(req, res, next) {
res.json(courses);
});
router.post('/json', function(req, res, next) {
console.log(req.body);
res.json({response: 200});
});
function mapStateToProps(state, ownProps) {
return {
courses: state.courses,
resposne: state.resposne
};
}
最佳答案
假设:
state.courses最初是一个空数组 - 来自 course.reducer.js fetchCourses()第一次渲染 View 时的操作 fetchCourses()只要courses就没有问题server.js 中是一个数组(响应中的数组替换了初始的 state.courses )<input type="text">和 submit按钮。现在,当您输入标题并单击 submit 时按钮,onSave()方法触发 createCourse()参数或多或少类似于 { title: 'something' } 的操作.createCourse() 中),服务器又返回一个看起来像 {response: 200} 的响应(在 server.js 中)。响应字段是一个整数和 不是 大批!走得更远你打电话loadCourses()与对象 {response: 200}这会触发 courseReducer在 course.reducer.jscourseReducer() 替换 state.courses (根据假设是 [] )一个整数。这个状态更新会触发重新渲染,你最终会调用 map()在整数上而不是在数组上,从而导致 TypeError: this.props.courses.map is not a function .course 对象),或 state.courses数组,例如,return [...state, action.response] loadData()同 course您调用的对象 createCourse()在您的 reducer 中使用和(如上所述),而不是替换或改变旧数组,而是创建一个新数组并将类(class)对象附加到它,在 es6 中,您可以执行以下操作,return [...state, course] .Actions are payloads of information that send data from your application to your store. They are the only source of information for the store.
createCourse()使用或多或少类似的有效载荷调用 Action ,{title: 'Thing you entered in Text Field'} ,然后您使用 AJAX 请求调用您的服务器并将有效负载传递给服务器,然后服务器验证有效负载并根据您的逻辑发送成功(或错误)响应。服务器响应看起来像,{response: 200} . createCourse() 到此结束行动。现在你dispatch() loadCourses()来自内部的行动 createCorse() ,与您从服务器收到的响应,这不是您想要的(基于您的评论)。因此,请尝试 dispatch()像这样执行操作(尝试重命名 response 参数,这有点令人困惑)//.....
.then(data => {
dispatch(loadCourse(response)); // the same payload you called createCourse with
})
//.....
现在,loadCourse()是一个非常基本的操作,它只是转发参数,Redux 使用它来调用您的 reducer .现在,如果您遵循之前的讨论并更新了您如何拨打 loadCourse() ,然后从 loadCourse() 返回好像{
type: REQUEST_POSTS,
response: {
title: 'Thing you entered in Text Field',
}
}
然后传递给您的 reducer ,特别是您的 courseReducer() .Actions describe the fact that something happened, but don't specify how the application's state changes in response. This is the job of reducers.
reducer必须定义操作应该如何影响 store 中的数据的逻辑。 .courseReducer() ,您只需返回 response action 内的字段object 和 [期望] Redux 自动神奇地改变你的状态!不幸的是,这不是发生的事情:({ courses: [{...}, {...}, {...}] }
然后你从你的 reducer 返回这样的东西{ title: 'Thing you entered in Text Field'}
然后 redux 将更新状态看起来像{ courses: { title: 'Thing you entered in Text Field'} }
state.courses 不再是一个数组!export default function courseReducer(state = [], action) {
switch (action.type) {
case 'REQUEST_POSTS':
return [...state, action.response]
default:
return state
}
}
旁注 :这有时可能会令人困惑,所以只是为了记录,state内courseReducer()不是完整状态,而是 property在 state reducer管理。您可以阅读有关此内容的更多信息 here
关于javascript - React - TypeError : this. props.courses.map 不是函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44418362/
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只
HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
我需要一个通过输入字符串进行计算的方法,像这样function="(a/b)*100"a=25b=50function.something>>50有什么方法吗? 最佳答案 您可以使用instance_eval:function="(a/b)*100"a=25.0b=50instance_evalfunction#=>50.0请注意,使用eval本质上是不安全的,尤其是当您使用外部输入时,因为它可能包含注入(inject)的恶意代码。另请注意,a设置为25.0而不是25,因为如果它是整数a/b将导致0(整数)。
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的
在Ruby(尤其是Rails)中,您经常需要检查某物是否存在,然后对其执行操作,例如:if@objects.any?puts"Wehavetheseobjects:"@objects.each{|o|puts"hello:#{o}"end这是最短的,一切都很好,但是如果你有@objects.some_association.something.hit_database.process而不是@objects呢?我将不得不在if表达式中重复两次,如果我不知道实现细节并且方法调用很昂贵怎么办?显而易见的选择是创建一个变量,然后测试它,然后处理它,但是你必须想出一个变量名(呃),它也会在内存中
如果names为nil,则以下中断。我怎样才能让这个map只有在它不是nil时才执行?self.topics=names.split(",").mapdo|n|Topic.where(name:n.strip).first_or_create!end 最佳答案 其他几个选项:选项1(在其上执行map时检查split的结果):names_list=names.try(:split,",")self.topics=names_list.mapdo|n|Topic.where(name:n.strip).first_or_create!e