React generated button on my form keeps refreshing the page

20,795

Solution 1

Sounds to me like a delegation issue - I'll bet #chat isn't in the DOM when you are creating the submit handler.

Try delegating the submit to the document (and preventing the default action):

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

Solution 2

This is default HTML behavior. Buttons are submit buttons by default, so clicking them will submit the form. If you don't want that, then make it a "dumb" button:

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

You could also simply remove the <form> element since you don't seem to do anything with it.


The other issue is, as explained in the other answer, that you are trying to bind the event handler before the button exists.

The way you mix jQuery and React is messy, makes your code harder to maintain and harder to reason about. Just keep everything inside the React component:

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>
        );
    }
});

Similarly, messageData should be part of the state of the component, but I leave the conversion up to you.

Basically the way you use React currently doesn't give you much benefit. I recommend to read more of the React documentation, especially Thinking in React and Interactivity and Dynamic UIs.

Solution 3

Your problem is something to do with controlled and uncontrolled components in React. In uncontrolled component: If you are not calling a handler function to handle the submit OR If you do not turn off the default behavior of the HTML,then Submit button would alwaysbe handled by the DOM.

In controlled component: A handler function would take care of the action upon submit. Example for controlled component:

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>

Detailed discussion is here: https://facebook.github.io/react/docs/uncontrolled-components.html https://facebook.github.io/react/docs/forms.html

Share:
20,795

Related videos on Youtube

GenericAlias
Author by

GenericAlias

im a student

Updated on July 09, 2022

Comments

  • GenericAlias
    GenericAlias almost 2 years

    I was trying to make a chat application using node.js and react.js, but I cannot get past this issue where every time I click my page's button it refreshes the page. I'm fairly new to web development so forgive me if my issue is extremely obvious. My code can be found below:

    // 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')
    );
    

    Here is the relevant 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>
    

    For some reason the alert in my submit function is never reached. It just refreshes the page whenever I hit the button. I'm not sure whether this is an issue with React, jQuery, or just some odd thing that I missed with my HTML. I already tried using 'onsubmit = "return false"' in my button and preventDefault() as well but was still unable to pinpoint the problem. How do I fix my page's behavior, and what tools might I consider using to analyze this issue more closely?

    • depperm
      depperm almost 9 years
      whats the relevant html?
  • GenericAlias
    GenericAlias almost 9 years
    Yeah, I think you're right. I think that pattern will also work well for the functionality of the page as well. Thanks!
  • Felix Kling
    Felix Kling almost 9 years
    @GenericAlias: Just keep in mind that while this may provide a short term solution, you really should refactor your code to use React properly.
  • Admin
    Admin over 8 years
    THANK YOU! I have been looking at why my page was refreshing for a few hours now, type="button" did it!!