J
J
Johniq2017-10-14 17:28:56
JavaScript
Johniq, 2017-10-14 17:28:56

How to correctly push objects into an array of objects?

There are data (messages) that come from the database (firebase), I sort through them with a forward and push them into the this.state.messages array, I write the first message in chrome, the second in safari, here is a clear example of what happens, how to make the message not copied?

the code
import React from 'react';
import axios from 'axios';
import './App.css';
import io from 'socket.io-client';
import constants from '../../constants';
import firebase from 'firebase';

class App extends React.Component {
    constructor() {
        super();

        this.state = {
            socket: io('localhost:8000'),
            messages: [],
            userName: JSON.parse(localStorage.getItem('userName'))
        }
    }

    componentDidMount() {
        this.fetchMessages();
    }

    fetchMessages = () => {
        const ref = firebase.database().ref("messages");

        ref.on("value", snapshot => {
            snapshot.forEach(childSnapshot => {
                let data = childSnapshot.val();
                let messages = this.state.messages.slice();
                messages.push(data);

                this.setState({ messages });
            });
        }, error => {
            console.log(error);
        });
    };

    handleAddNickName = e => {
        e.preventDefault();
        const userName = this.refs.usernameRef.value;

        localStorage.setItem('userName', JSON.stringify(userName));
        this.setState({ userName });
    };

    handleNewMessage = e => {
        e.preventDefault();

        const message = {
            msg: this.refs.messageRef.value,
            userName: this.state.userName
        };

        this.state.socket.emit('NEW_MESSAGE', message);
        firebase.database().ref('messages').push(message);

        this.refs.messageRef.value = '';
    };

    render() {
        const { messages, userName } = this.state;
        const { handleNewMessage, handleAddNickName } = this;

        return (
            <div className="app">
                <header className="header">
                    <h1 className="logo">React Chat</h1>
                </header>

                { userName ?
                    <div className="chat-container">
                        <ul>
                            {
                                messages.length !== 0 ?
                                    messages.map((item, i) => {
                                        return <li key={ i }><strong>{ item.userName }</strong>: { item.msg }</li>
                                    })
                                    :
                                    <p>Loading...</p>

                            }
                        </ul>

                        <div className="chat-controllers">
                            <input type="text" ref="messageRef"/> <button onClick={ handleNewMessage }>Send</button>
                        </div>
                    </div>

                    :

                    <div className="nickname-container">
                        <input type="text" placeholder="Your nickname" ref="usernameRef" /> <button onClick={ handleAddNickName }>Go</button>
                    </div>
                }
            </div>
        )
    }
}

export default App;

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
alvvi, 2017-10-14
@alvvi

1. Do not use indexes as keys.
If the problem persists:
2. Open devtools, debug the component's state. Or put it in a sandbox so that others can debug.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question