[英]onClick called repeatedly (not supposed to) when component re-renders
我有一個反應成分是一種形式。 當用戶單擊發送/提交按鈕時,將調用一個函數來處理數據保存並執行其他一些任務。
問題是用戶單擊按鈕后,該組件似乎重新渲染了幾次(最可能是因為從其他組件接收到的外部道具已更新)。 這本身不是問題。
但是,當組件更新時,即使用戶沒有再次單擊按鈕, onClick
函數也會被再次調用。
這是我不明白的部分。 為什么組件更新時會觸發onClick
函數? 以及如何防止這種情況發生?
我不想在用戶單擊按鈕后停止更新組件。 因為用戶可能想要更改表單中的某些內容然后再次發送。
概括地說,該組件如下所示:
class Form extends Component{ constructor(props) { super(props); this.state = { input: '', } } save() { // do something // and something else... alert('data saved!'); } render() { return ( <div> <div> <input type="text" onChange={(e) => {this.setState({input: e.target.value})}} value={this.state.input} /> </div> <div onClick={this.save.bind(this)}> <span>submit</span> </div> </div> ) } }
*更新*我想我知道出了什么問題。
我在上面的文章中沒有提到的是,在save
函數中有一個firebase auth事件偵聽器,以確保對用戶進行身份驗證。 它看起來像這樣:
save () {
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// do something
// and something else
alert('data saved');
} else {
// do something else
}
});
}
該事件偵聽器由於某種原因在用戶提交后被觸發多次(不應觸發)。 底線是他與組件更新無關。
我現在為事件偵聽器分配了一個值,並在觸發一次后將其設置為null,如下所示:
save () {
const that = this;
this.firebaseListener = firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// do something
// and something else
alert('data saved');
that.firebaseListener = null;
} else {
// do something else
}
});
this.firebaseListener && this.firebaseListener();
}
到目前為止,這似乎一直在起作用...
關於您的Firebase困境,請參見以下答案: 如何在react中刪除新的firebase onAuthStateChanged偵聽器
聽起來您處在正確的軌道上,但是您可能希望在生命周期的早期階段設置auth偵聽器。 這樣,您的用戶在嘗試保存表單之前就知道他們已經登錄。 不過,取決於您的用例。
不要使用箭頭功能或在render
bind
。 改為這樣做:
class Form extends Component{
constructor(props) {
super(props);
this.state = {
input: '',
}
this.handleChange = this.handleChange.bind(this);
this.save = this.save.bind(this);
}
handleChange(e) {
this.setState({input: e.target.value});
}
save() {
// do something
// and something else...
alert('data saved!');
}
render() {
return (
<div>
<div>
<input
type="text"
onChange={this.handleChange}
value={this.state.input}
/>
</div>
<div onClick={this.save}>
<span>submit</span>
</div>
</div>
)
}
}
此更改應修復您的窗體的重新呈現。 這是因為每次調用render時函數都會更改,這會觸發重新渲染。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.