web-dev-qa-db-de.com

Generierte Schaltfläche "Reagieren" in meinem Formular aktualisiert die Seite ständig

Ich habe versucht, eine Chat-Anwendung mithilfe von node.js und react.js zu erstellen, aber ich kann dieses Problem nicht umgehen, in dem jedes Mal, wenn ich auf die Schaltfläche meiner Seite klicke, die Seite aktualisiert wird. Ich bin ziemlich neu in der Webentwicklung, also verzeihen Sie mir, wenn mein Problem extrem offensichtlich ist. Mein Code ist unten zu finden:

// Array of messages to be rendered
messageArray = [];
var socket = io();
// Prompt the user for their username
var user = Prompt("Please enter your name", "Anonymous");
// Emit username information so that it can be kept track of
socket.emit('new user', user);


$('#chat').submit(function() {
    // When the user hits submit, create a message object with 
    // information about their name, time sent, message, and socket id.
    // The socket id will be filled on the server side
    alert("hey");
    var date = new Date();
    var message = user + " (" + date.toLocaleTimeString('en-US') + "): " + $('#m').val();
    var messageJSON = {text:message, username:user, id:"", time:date}
    socket.emit('chat message', messageJSON);
    // Reset the value field
    $('#m').val('');
    return false;
});

// On receiving a chat message, update messageArray and 
// rerender the ViewingBox
socket.on('chat message', function(messages){
    messageArray = [];
    for (var i = 0; i < messages.length; i++) {
        alert(messages[i].text)
        messageArray.Push(messages[i].text);
    }

    React.render(
        <ViewingBox />,
        document.getElementById('root')
    );
});

// ViewingBox holds the view of the page and is updated whenever
// a new message is received
var ViewingBox = React.createClass({
    render: function() {
        return (
            <div>
                <h2>Global Chat: Logged in as {user}</h2>

                <ul id="messages">
                    {messageArray.map(function(data, i) {
                        return (<li>{data}</li>)
                    })} 
                </ul>
                <form id="chat" action="#">
                    <input id="m" autoComplete = "off" />
                     /*
                     *
                     Button in question
                     *
                     */
                    <button>Send</button>
                </form>
            </div>
        );
    }
});


// Render the viewingBox when the page initially loads
React.render(
    <ViewingBox />,
    document.getElementById('root')
);

Hier ist das relevante HTML:

<!doctype html>
<html>
  <head>
    <title>Socket.IO chat</title>
    <style>
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
      form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
    </style>
  </head>
  <body>
    <div id="root"></div>
    <script src="https://fb.me/react-0.13.3.js"></script>
    <script src="https://fb.me/JSXTransformer-0.13.3.js"></script>
    <script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
    <script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>  
    <script type="text/jsx" src="/reactclient.js"></script> 
  </body>
</html>

Aus irgendeinem Grund wird die Warnung in meiner Übermittlungsfunktion nie erreicht. Die Seite wird nur aktualisiert, wenn ich die Schaltfläche drücke. Ich bin mir nicht sicher, ob es sich um ein Problem mit React, jQuery oder nur um eine seltsame Sache handelt, die ich mit meinem HTML-Code vermisst habe. Ich habe bereits versucht, 'onsubmit = "return false"' in meinem Button zu verwenden. Dies gilt jedoch auch für PrevDefault (), konnte das Problem jedoch immer noch nicht feststellen. Wie kann ich das Verhalten meiner Seite korrigieren und mit welchen Tools könnte ich dieses Problem genauer analysieren?

14
GenericAlias

Klingt für mich wie ein Delegierungsproblem - Ich wette, dass #chat nicht im DOM ist, wenn Sie den Submit-Handler erstellen.

Versuchen Sie, die Übermittlung an das Dokument zu delegieren (und die Standardaktion zu verhindern):

$(document).on('submit','#chat',function(e) {
 e.preventDefault();
 ...
});
11
Adam

Dies ist das Standardverhalten von HTML. Schaltflächen sind standardmäßig Schaltflächen zum Senden. Wenn Sie auf diese klicken, wird das Formular gesendet. Wenn Sie das nicht möchten, machen Sie es zu einer "dummen" Schaltfläche:

<button type="button">Send</button>

Sie können das <form>-Element auch einfach entfernen, da Sie damit scheinbar nichts zu tun haben.


Das andere Problem ist, wie in der anderen Antwort erläutert, dass Sie versuchen, den Ereignishandler zu binden, bevor die Schaltfläche vorhanden ist.

Die Art und Weise, wie Sie jQuery und React mischen, ist unordentlich, macht es schwieriger, Ihren Code zu verwalten und schwerer zu denken. Behalten Sie einfach alles in der React-Komponente:

var ViewingBox = React.createClass({
    getInitialState: function() {
        return {
            message: ''
        };
    },

    _onMessageChange: function(event) {
        this.setState({message: event.target.value});
    },

    _send: function() {
        var date = new Date();
        var message = user + " (" + date.toLocaleTimeString('en-US') + "): " + this.state.message;
        var messageJSON = {text:message, username:user, id:"", time:date}
        socket.emit('chat message', messageJSON);
        // Reset the value field
        this.setState({message: ''});
    },

    render: function() {
        return (
            <div>
                <h2>Global Chat: Logged in as {user}</h2>

                <ul id="messages">
                    {messageArray.map(function(data, i) {
                        return (<li>{data}</li>)
                    })} 
                </ul>
                <form id="chat" action="#">
                    <input
                        value={this.state.message}
                        onChange={this._onMessageChange}
                        autoComplete="off"
                    />
                    <button type="button" onClick={this._send}>Send</button>
                </form>
            </div>
        );
    }
});

Ebenso sollte messageData Teil des Zustands der Komponente sein, aber ich überlasse Ihnen die Konvertierung.

Grundsätzlich bringt die Art und Weise, wie Sie React einsetzen, keinen großen Nutzen. Ich empfehle, mehr in der React-Dokumentation zu lesen , insbesondere Thinking in React und Interaktivität und dynamische UIs .

36
Felix Kling

Ihr Problem hat etwas mit kontrollierten und unkontrollierten Komponenten in React zu tun. In einer unkontrollierten Komponente: Wenn Sie keine Handler-Funktion aufrufen, um das Submit zu verarbeiten OR. Wenn Sie das Standardverhalten des HTML-Codes nicht deaktivieren, wird die Schaltfläche Submit immer vom DOM behandelt.

In einer kontrollierten Komponente: Eine Handler-Funktion würde die Aktion beim Senden übernehmen. Beispiel für eine gesteuerte Komponente: 

handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    **event.preventDefault();**
  }

<form onSubmit={**this.handleSubmit**}>
    <label>
      Name:
      <input type="text" value={this.state.value} onChange={this.handleChange} />
    </label>
    <input type="submit" value="Submit" />
  </form>

Ausführliche Diskussionen finden Sie hier: https://facebook.github.io/react/docs/uncontrolled-components.htmlhttps://facebook.github.io/react/docs/ forms.html

1
Vish