2

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

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

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

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

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

问题:

如果另一个客户端更新集合,我希望文本框显示更新的值。为此,我必须this.state在函数内部进行更新getMeteorData(),但这是不允许的,并且出现错误:“Calling setState inside getMeteorData can result in infinite loop”

现在我有一个解决方法,我手动更新 and 中的文本框值componentDidMount()getMeteorData()但感觉很hackish,我一点也不喜欢它。

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

4

1 回答 1

1

我会完全摆脱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);

theContainer充当容器组件,并theComponent通过 props 将包含的数据传输到表示组件。请注意,给定的函数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)以保存数据传输。

于 2016-07-09T09:17:46.103 回答