Reactコンポーネントには、クリックされたときにAJAX経由でデータを送信するためのボタンがあります。私は最初にだけ、つまり最初に使用した後にボタンを無効にする必要があります。
私がこれをやろうとしている方法:
var UploadArea = React.createClass({
getInitialState() {
return {
showUploadButton: true
};
},
disableUploadButton(callback) {
this.setState({ showUploadButton: false }, callback);
},
// This was simpler before I started trying everything I could think of
onClickUploadFile() {
if (!this.state.showUploadButton) {
return;
}
this.disableUploadButton(function() {
$.ajax({
[...]
});
});
},
render() {
var uploadButton;
if (this.state.showUploadButton) {
uploadButton = (
<button onClick={this.onClickUploadFile}>Send</button>
);
}
return (
<div>
{uploadButton}
</div>
);
}
});
起こると思うのは、状態変数showUploadButton
がすぐに更新されないことです。これはReactのドキュメントが期待していることです。
クリックされた瞬間にボタンを強制的に無効にしたり、まとめて削除したりするにはどうすればよいですか?
あなたができることは、クリックされた後にボタンを無効にし、それをページに残します(クリック可能な要素ではありません)。
これを実現するには、ボタン要素に参照を追加する必要があります
<button ref="btn" onClick={this.onClickUploadFile}>Send</button>
そして、onClickUploadFile関数でボタンを無効にします
this.refs.btn.setAttribute("disabled", "disabled");
それに応じて、無効なボタンのスタイルを設定して、ユーザーにフィードバックを提供できます。
.btn:disabled{ /* styles go here */}
必要に応じて、次のコマンドで再度有効にしてください。
this.refs.btn.removeAttribute("disabled");
更新:Reactの参照を処理する好ましい方法は、文字列ではなく関数を使用することです。
<button
ref={btn => { this.btn = btn; }}
onClick={this.onClickUploadFile}
>Send</button>
this.btn.setAttribute("disabled", "disabled");
this.btn.removeAttribute("disabled");
ここに、提供したコードを使用した小さな例があります https://jsfiddle.net/69z2wepo/30824/
解決策は、ハンドラーに入るとすぐに状態をチェックすることです。 Reactは、インタラクティブイベント(クリックなど)内のsetStateがブラウザイベント境界でフラッシュされることを保証します。参照: https://github.com/facebook/react/issues/11171# issuecomment-357945371
// In constructor
this.state = {
disabled : false
};
// Handler for on click
handleClick = (event) => {
if (this.state.disabled) {
return;
}
this.setState({disabled: true});
// Send
}
// In render
<button onClick={this.handleClick} disabled={this.state.disabled} ...>
{this.state.disabled ? 'Sending...' : 'Send'}
<button>
動作するものとしてテスト済み: http://codepen.io/zvona/pen/KVbVPQ
class UploadArea extends React.Component {
constructor(props) {
super(props)
this.state = {
isButtonDisabled: false
}
}
uploadFile() {
// first set the isButtonDisabled to true
this.setState({
isButtonDisabled: true
});
// then do your thing
}
render() {
return (
<button
type='submit'
onClick={() => this.uploadFile()}
disabled={this.state.isButtonDisabled}>
Upload
</button>
)
}
}
ReactDOM.render(<UploadArea />, document.body);
React Hooks を使用して Component State を設定してみてください。
import React, { useState } from 'react';
const Button = () => {
const [double, setDouble] = useState(false);
return (
<button
disabled={double}
onClick={() => {
// doSomething();
setDouble(true);
}}
/>
);
};
export default Button;
使用していることを確認してください^16.7.0-alpha.x
バージョンのreact
およびreact-dom
。
これがあなたを助けることを願っています!
必要に応じて、送信を禁止します。
lodash.js debounce
イベント(キーストロークなど)の突然のバーストを1つのイベントにグループ化します。
https://lodash.com/docs/4.17.11#debounce
<Button accessible={true}
onPress={_.debounce(async () => {
await this.props._selectUserTickets(this.props._accountId)
}, 1000)}
></Button>
const once = (f, g) => {
let done = false;
return (...args) => {
if (!done) {
done = true;
f(...args);
} else {
g(...args);
}
};
};
const exampleMethod = () => console.log("exampleMethod executed for the first time");
const errorMethod = () => console.log("exampleMethod can be executed only once")
let onlyOnce = once(exampleMethod, errorMethod);
onlyOnce();
onlyOnce();
output
exampleMethod executed for the first time
exampleMethod can be executed only once