如何修复react-redux中的“ TypeError:this.props.messages.map不是函数”

时间:2019-04-03 11:59:48

标签: reactjs redux react-redux

我正在尝试通过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的代码编辑器中映射一个对象,但现在还不能呢?以及如何解决此问题?

3 个答案:

答案 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)