当前位置: 首页 > 知识库问答 >
问题:

onClick在组件重新渲染时重复调用(不应该)

谷永贞
2023-03-14

我有一个反应组件,它是一种形式。当用户单击发送/提交按钮时,将调用一个函数来处理数据保存并执行一些其他任务。

问题是在用户单击按钮后,组件似乎重新渲染了几次(很可能是因为它从其他组件接收的外部道具更新了)。这本身不是问题。

但是,当组件更新时,即使用户没有再次单击该按钮,也会再次调用onClick函数。

这是我不明白的部分。为什么组件更新时会触发< code>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>
    )
  }
}

*更新,我想我知道出了什么问题。

我在上面的帖子中没有提到的是,在< code>save函数中有一个firebase auth事件监听器,用于确保用户通过身份验证。它看起来像这样:

save () {
  firebase.auth().onAuthStateChanged(function(user) {
              if (user) {
                 // do something
                 // and something else
                 alert('data saved');
              } else {
                // do something else
              }
  });
}

在用户提交之后,由于某种原因,事件监听器被触发了多次(不应该触发)。底线是his与组件更新无关。

现在,我已为事件侦听器分配了一个值,并在触发一次后将其设置为 null,如下所示:

save () {
  const that = this;
  this.html" target="_blank">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();
}

到目前为止,这似乎是有效的...

共有1个答案

汪成仁
2023-03-14

关于你的firebase困境,请看这个答案:如何在react中删除新的firebase onAuthStateChanged监听器

听起来您的方向是正确的,但您可能希望在生命周期的早期设置auth侦听器。这样,您的用户在尝试保存表单之前就知道他们已经登录了。不过,这取决于您的用例。

不要在渲染中使用箭头函数或绑定。请改为执行以下操作:

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时函数都会更改,这可能会触发重新呈现。

 类似资料:
  • 我对react还比较陌生,我一直在分解一个web应用程序,并用react组件替换部分。我现在正在开发一个组件,其中包含我创建的几个不同组件。 在新组件中,我在componentDidMount函数中进行API调用,并创建子组件。乍一看,一切看起来都很完美,但当我们在其中一个子组件中进行状态更改,然后在父组件中进行更改时,子组件将其状态重置为更改之前的状态。 我知道发生了什么,州政府没有被传递给家长

  • 我有一个组件,我想在用户点击后显示/隐藏。 它是这样的: 和 只需将wasPressed属性适当地设置为true或false。我正在使用<代码> 问题是“我的按钮”的“渲染”属性的值。它明确地包括两个方面:解释和显示按钮。 只要始终存在(它只更改它的标签),仅在属性为真时才存在。否则它说: malformedXML:更新期间:找不到解释 我如何解决这个问题? 我不想恢复到在源代码中隐藏元素,所以我

  • 看看这支笔:https://codepen.io/segmentationfaulter/pen/XzgJyV 为了方便起见,我还在这里粘贴代码。打开上面的画笔后,您将看到一个滑块被渲染。向右滚动滑块,然后单击按钮,您将看到滑块以不同的数字重新渲染,但滑块的滚动位置不会重置。为什么滚动位置没有复位?谢谢

  • 问题内容: 我正在尝试将表示性组件与容器组件分开。我有一个和一个。容器负责触发redux操作,以根据当前用户获取适当的网站。 问题是在最初呈现容器组件之后,异步获取了当前用户。这意味着容器组件不知道它需要重新执行其函数中的代码,该代码将更新数据以发送到。我认为我需要在其props(user)之一更改时重新渲染容器组件。如何正确执行此操作? 问题答案: 您必须在方法中添加条件。 该示例用于比较对象。

  • 所以这是我的第一个组件,我减速我的路线。我决定做两个导航项目。做了一些造型。但我得到的错误,许多重新渲染。因为我尝试添加带有悬停效果的样式。我不想使用css。这是我的代码:

  • 我有一个带有两组按钮(功能和目标)的界面。当我点击一个按钮时,我希望它从一个团队转到另一个团队。我正在用react和redux实现这一点。我唯一的问题是,当状态更新并且我成功地记录了更新的状态时,除非我使用forceUpdate(),否则组件不会更新。我不明白的是,既然状态更新成功,组件不应该自动重新渲染吗? 一些js 正如您所看到的,当我单击一个按钮时,我触发updateLists函数,该函数将