使用debounce将React状态同步到Meteor集合

Sync React state to Meteor collection using debounce

本文关键字:Meteor 集合 同步 状态 debounce React 使用      更新时间:2023-09-26

我的Meteor+React应用程序中有一个文本框。我想将它的值同步到Mongo集合。然而,我不想在每次击键后更新集合,只有当用户停止键入几秒钟时。

我的render()函数中的文本框如下所示:

<input type="text" ref="answerswer" onChange={this.onChange} value={this.state.someValue} />

我将文本框值存储在this.state而不是this.data中,因为this.data反映了Mongo集合,该集合可能尚未更新。

到目前为止,所有这些都有效。

问题:

如果另一个客户端更新了集合,我希望文本框显示更新后的值。为此,我必须在getMeteorData()函数中更新this.state,但这是不允许的,并且我得到一个错误:"在getMeteorData中调用setState可能导致无限循环"

现在我有一个变通方法,可以手动更新componentDidMount()getMeteorData()中的文本框值,但感觉很粗糙,我一点也不喜欢。

有更好的方法吗?如果我保证我会成为一个好孩子,表现得很好,我可以在getMeteorData()中强制更新状态吗?

我会完全摆脱getMeteorData,转而使用createContainer。数据流在大多数情况下都变得清晰和简单,包括这个特定的案例。它来了。

首先,创建一个容器来获取数据。

export default theContainer = createContainer(() => {
  // Subscribe to the publication which publishes the data.
  const subscription = Meteor.subscribe(...);
  // Derive the data for the input box and form the props to pass down.
  const props = {
    answer: getAnswer(subscription)
  };
  return props;
}, theComponent);

CCD_ 12充当容器组件,并通过props将包含的数据传输到表示组件CCD_。请注意,赋予createContainer的函数是响应的,这意味着该函数中对响应数据源的更改会触发重新运行并导致theComponent的重新发布。

现在我们都武装起来了。由于Mongo集合(确切地说是Minimongo)中的数据是通过传递的道具同步的,theComponent通过道具转换知道同步。

export default class theComponent extends React.Component {
  ...
  componentWillReceiveProps(nextProps) {
    if (this.props.answer !== nextProps.answer) {
      this.setState({
        answer: nextProps.answer
      });
    }
  }
  render() {
    return <input value={this.state.answer} onChange={this.onChange} />;
  }
}

当发生这种转换时,即将到来的值被更新为状态,并且该受控组件将基于更新的新值来呈现输入。

另一方面,当用户开始键入时,更改处理程序this.onChange将用户的输入更新为每个键的状态,因为这是一个受控组件。然而,只有当预设的持续时间已经过去时,处理程序才会更新Mongo集合(同样是Minimongo)以保存数据传输。