javascript 我的表单上反应生成的按钮不断刷新页面
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31039187/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
React generated button on my form keeps refreshing the page
提问by GenericAlias
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:
我试图使用 node.js 和 react.js 制作一个聊天应用程序,但我无法解决这个问题,每次我点击我页面的按钮时,它都会刷新页面。我对 Web 开发还很陌生,所以如果我的问题非常明显,请原谅我。我的代码可以在下面找到:
// 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:
这是相关的 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?
出于某种原因,我的提交功能中的警报从未达到。每当我点击按钮时,它都会刷新页面。我不确定这是 React、jQuery 的问题,还是我在 HTML 中遗漏的一些奇怪的东西。我已经尝试在我的按钮和 preventDefault() 中使用 'onsubmit = "return false"' 但仍然无法查明问题。如何修复我的页面行为,我可以考虑使用哪些工具来更仔细地分析此问题?
采纳答案by Adam
Sounds to me like a delegation issue - I'll bet #chat
isn't in the DOM when you are creating the submit handler.
听起来像一个委托问题 - 我敢打赌#chat
,当您创建提交处理程序时,它不在 DOM 中。
Try delegating the submit to the document (and preventing the default action):
尝试将提交委托给文档(并阻止默认操作):
$(document).on('submit','#chat',function(e) {
e.preventDefault();
...
});
回答by Felix Kling
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:
这是默认的 HTML 行为。默认情况下,按钮是提交按钮,因此单击它们将提交表单。如果你不想这样,那就把它变成一个“哑”按钮:
<button type="button">Send</button>
You could also simply remove the <form>
element since you don't seem to do anything with it.
您也可以简单地删除该<form>
元素,因为您似乎没有对它做任何事情。
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:
你混合 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>
);
}
});
Similarly, messageData
should be part of the state of the component, but I leave the conversion up to you.
同样,messageData
应该是组件状态的一部分,但我将转换留给您。
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 Reactand Interactivity and Dynamic UIs.
基本上,您目前使用 React 的方式并没有给您带来太多好处。我建议阅读更多React 文档,尤其是Thinking in Reactand Interactivity and Dynamic UIs。
回答by Vish
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.
您的问题与 React 中的受控和非受控组件有关。在不受控制的组件中:如果您没有调用处理程序函数来处理提交或如果您不关闭 HTML 的默认行为,则提交按钮将始终由 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.htmlhttps://facebook.github.io/react/docs/forms.html
详细讨论在这里:https: //facebook.github.io/react/docs/uncontrolled-components.html https://facebook.github.io/react/docs/forms.html