Вновь созданная кнопка в моей форме продолжает обновлять страницу
Я пытался сделать чат-приложение с помощью node.js и response.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" в моей кнопке и preventDefault(), но не смог точно определить проблему. Как исправить поведение моей страницы и какие инструменты я могу использовать для более эффективного анализа этой проблемы?
Ответы
Ответ 1
Звучит для меня как проблема с делегацией - я ставлю, что #chat
не находится в DOM, когда вы создаете обработчик отправки.
Попробуйте делегировать отправку документа (и предотвратить действие по умолчанию):
$(document).on('submit','#chat',function(e) {
e.preventDefault();
...
});
Ответ 2
Это поведение по умолчанию 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 documentation, особенно Мышление в действии и Интерактивность и динамические интерфейсы.
Ответ 3
Ваша проблема связана с контролируемыми и неконтролируемыми компонентами в React.
В неконтролируемом компоненте: Если вы не вызываете функцию обработчика для обработки отправки ИЛИ Если вы не отключите поведение 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.html
https://facebook.github.io/react/docs/forms.html