简体   繁体   中英

ReactJS render an array of items inside the state

I'm trying to render a list of items but I got this error:

Objects are not valid as a React child (found: [object MessageEvent]). If you meant to render a collection of children, use an array instead.
    in li (at Chat.js:51)
    in ul (at Chat.js:47)
    in div (at Chat.js:70)
    in div (at Chat.js:63)
    in Chat (created by Context.Consumer)
    in Route (created by withRouter(Chat))
    in withRouter(Chat) (created by Context.Consumer)
    in Route (at App.js:14)
    in Switch (at App.js:12)
    in Router (created by BrowserRouter)
    in BrowserRouter (at App.js:11)
    in App (at src/index.js:12)
    in Router (created by BrowserRouter)
    in BrowserRouter (at src/index.js:11)

The messages array is populated by the connected websocket. This is what I did:

import React, { Component } from 'react';
import './Home.css';
import { withRouter } from 'react-router-dom';

class Chat extends Component {

    constructor() {
        super();

        this.state = {
            username: '',
            ws: '',
            message: '',
            messages: [],
        }

        this.handleMessageChanged = this.handleMessageChanged.bind(this);
        this.sendMessage = this.sendMessage.bind(this);
    }

    componentDidMount() {
        const self = this;
        this.setState({
            username: this.props.history.location.state.username,
            ws: new WebSocket(`ws://localhost:3001?username=${ this.props.history.location.state.username }`),
        }, () => {
            this.state.ws.addEventListener('message', (message) => {
                self.setState({ messages: [...self.state.messages, message] });
            });
        });
    }

    handleMessageChanged(event) {
        this.setState({ message: event.target.value });
    }

    sendMessage(event) {
        if (event.key === 'Enter') {
            this.state.ws.send(this.state.message);
            this.setState({ message: '' });
        }
    }

    renderMessages() {
        let messages = this.state.messages;
        return (
            <ul>
                {
                    messages.map((message, index) => {
                        return (
                            <li key={index}>
                                {message}
                            </li>
                        );
                    })
                }
            </ul>
        );
    }

    render() {
        return (
        <div className="Chat">
            <header className="App-body">
            <p>
                <code>ChatApp</code>
            </p>
            </header>

            <div className="container App-body">
                {this.renderMessages()}
                <input className="form-control form-control-lg message-box" value={this.state.message} onKeyDown={this.sendMessage} onChange={this.handleMessageChanged} type="text" placeholder="Enter your message here" />
            </div>

        </div>
        );
    }
}

export default withRouter(Chat);

Do you know why I got this error?

I've also tried to call he renderMessages function with:

{this.renderMessages}

but I got this error:

Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.
    in div (at Chat.js:70)
    in div (at Chat.js:63)
    in Chat (created by Context.Consumer)
    in Route (created by withRouter(Chat))
    in withRouter(Chat) (created by Context.Consumer)
    in Route (at App.js:14)
    in Switch (at App.js:12)
    in Router (created by BrowserRouter)
    in BrowserRouter (at App.js:11)
    in App (at src/index.js:12)
    in Router (created by BrowserRouter)
    in BrowserRouter (at src/index.js:11)

This means that {message} in your renderMessages function is an object. Do some console.log s on that value. You may want to select a specific field from message .

You can't render object message in

<li key={index}>{message}</li>

Either replace it with

<li key={index}>{JSON.stringify(message)}</li>

or render <div> with message content

<li key={index}>
  <div>{message.prop}</div> <!-- I don't know what properties your object has -->
</li>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM