我正在尝试通过mapDispatchToProps()将道具向下传递到我的组件。但是,我遇到了这个问题
Enumerable.Except
如果取消注释第38行,则可以显示我的页面。但是,单击按钮后,我收到此错误消息:
TypeError: this.props.messages.map is not a function
DisplayMessages.render
C:/Users/User/Desktop/Project/first-react-redux/src/DisplayMessages.js:38
35 | <h2>Type in a new message</h2>
36 | <input value={input} onChange={this.handleChange} />
37 | <button onClick={this.submitMessage}>Submit</button>
> 38 | <ul>{this.props.messages.map((message, index) => <li key={index}>{message}</li>)}</ul>
| ^ 39 | </div >
40 | )
41 | }
我是React-redux的新手,我不确定出了什么问题。我当前正在处理的示例来自freecodecamp,我已经在代码编辑器中测试了这些代码并通过了挑战(除了这次我是在自己的计算机上进行操作并构造自己的文件树)。
这是我的组件的样子:
TypeError: Object(...) is not a function
submitNewMessage
C:/Users/User/Desktop/Project/first-react-redux/src/DisplayMessagesContainer.js:18
16 | return {
17 | submitNewMessage: (newMessage) => {
> 18 | dispatch(addMessage(newMessage))
19 | }
20 | }
21 | };
这是我的容器:
import React from 'react';
export default class DisplayMessages extends React.Component {
constructor(props) {
super(props);
this.state = {
input: '',
}
}
handleChange = (event) => {
this.setState({
input: event.target.value
})
}
submitMessage = () => {
this.props.submitNewMessage(this.state.input)
this.setState({
input: '',
})
}
render() {
const { input} = this.state
return (
<div>
<h2>Type in a new message</h2>
<input value={input} onChange={this.handleChange} />
<button onClick={this.submitMessage}>Submit</button>
<ul>{this.props.messages.map((message, index) => <li key={index}>{message}</li>)}</ul>
</div >
)
}
}
我的reducer.js:
import DisplayMessages from './DisplayMessages';
import { connect } from 'react-redux';
import addMessage from './redux/actions'
mapStateToProps
const mapStateToProps = (state) => {
return { messages: state }
};
const mapDispatchToProps = (dispatch) => {
return {
submitNewMessage: (message) => {
dispatch(addMessage(message))
}
}
};
const DisplayMessagesContainer = connect(mapStateToProps, mapDispatchToProps)(DisplayMessages)
export default DisplayMessagesContainer
我为动作创建者创建的action.js:
import { combineReducers } from 'redux';
import types from './types';
const defaultState = [];
const messageReducer = (state = defaultState, action) => {
switch (action.type) {
case types.ADD:
return [...state].concat(action.message)
break;
default:
return state
}
}
const rootReducer = combineReducers({
message: messageReducer
});
export default rootReducer;
还有我的type.js:
import types from './types.js';
const addMessage = (message) => {
return {
type: types.ADD,
message: message
}
}
export default {
addMessage,
}
那么我的代码到底出了什么问题?
对此有任何帮助。
谢谢
编辑: 我已经确认this.props.messages是一个Object而不是一个数组。但是我还有一个问题:为什么我可以在freecodecamp的代码编辑器中映射一个对象,但现在还不能呢?以及如何解决此问题?
答案 0 :(得分:0)
@chubbybunny map function
仅适用于数组。检查this.props.messages
是否为数组。
答案 1 :(得分:0)
1)您应该添加默认道具,例如 DisplayMessages.defaultProps = { 讯息:[] }
2)检查mapstatetoprops中的消息类型是数组还是对象。 3)地图仅适用于数组
答案 2 :(得分:0)
在减速器中您已定义
const rootReducer = combineReducers({
message: messageReducer
});
您应该这样设置mapStateToProps吗?
//mapStateToProps
const mapStateToProps = (state) => {
return { messages: state.message }
};
因为您不想将整个状态设置为消息道具(并且状态是对象),所以您希望将消息设置为state.message(消息=> reducer的名称)。
编辑
老实说我从来没有那样使用过mapDispatchToProps,我只是导入动作并将它们像第二个参数一样传递给connect(...)
actions
是您的默认导出,它包含函数addMessage
,该函数以及所有其他内容,当您这样传递道具时,它们将被放置在道具上。
如果您命名为export
//named export example
export const addMessage()...
//import would be like
import {addMessage} from './redux/actions'
//passing to connect would be like
export default connect(mapStateToProps, {addMessage});
和用法与下面的示例相同。
例如
import actions from './redux/actions'
// inside DisplayMessages i use action like
submitMessage = () => {
this.props.addMessage(this.state.input)
this.setState({
input: '',
})
}
export default connect(mapStateToProps, actions)(DisplayMessages)