it-swarm.com.ru

React сгенерированная кнопка в моей форме постоянно обновляет страницу

Я пытался создать приложение для чата, используя node.js и react.js, но я не могу обойти эту проблему, когда каждый раз, когда я нажимаю кнопку моей страницы, она обновляет страницу. Я довольно новичок в веб-разработке, поэтому простите меня, если моя проблема чрезвычайно очевидна. Мой код можно найти ниже:

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

Вот соответствующий 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>

По какой-то причине предупреждение в моей функции отправки никогда не достигается. Он просто обновляет страницу всякий раз, когда я нажимаю кнопку. Я не уверен, является ли это проблемой React, jQuery или просто какой-то странной вещью, которую я пропустил в своем HTML. Я уже пытался использовать "onsubmit =" return false "" в своей кнопке и предотвращатьDefault (), но все еще не смог точно определить проблему. Как я могу исправить поведение моей страницы и какие инструменты я мог бы использовать для более тщательного анализа этой проблемы?

14
GenericAlias

Для меня это похоже на проблему с делегированием - я готов поспорить, что #chat отсутствует в DOM, когда вы создаете обработчик отправки.

Попробуйте делегировать отправку в документ (и предотвратить действие по умолчанию):

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

Это поведение HTML по умолчанию. Кнопки являются кнопками отправки по умолчанию, поэтому при нажатии на них будет отправлена ​​форма. Если вы этого не хотите, сделайте «тупую» кнопку:

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

Вы также можете просто удалить элемент <form>, поскольку вы, похоже, ничего с ним не делаете.


Другая проблема, как объяснено в другом ответе, заключается в том, что вы пытаетесь связать обработчик событий до того, как кнопка существует.

То, как вы смешиваете jQuery и React, является грязным, делает ваш код сложнее поддерживать и труднее рассуждать. Просто держите все внутри компонента React:

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

Точно так же messageData должен быть частью состояния компонента, но я оставляю преобразование на ваше усмотрение.

По сути, то, как вы используете React в настоящее время, не приносит вам большой пользы. Я рекомендую прочитать больше документации React , особенно Thinking in React и Интерактивность и Динамические интерфейсы .

36
Felix Kling

Ваша проблема связана с управляемыми и неконтролируемыми компонентами в React. В неконтролируемом компоненте: если вы не вызываете функцию-обработчик для обработки отправки OR. Если вы не отключите поведение HTML по умолчанию, то кнопка Submit всегда будет обрабатываться DOM.

В контролируемом компоненте: функция обработчика позаботится о действии после отправки. Пример для контролируемого компонента: 

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>

Подробное обсуждение здесь: https://facebook.github.io/react/docs/uncontrolled-components.htmlhttps://facebook.github.io/react/docs/ forms.html

1
Vish