【问题标题】:Avoiding re-renders for controlled inputs in a React Flux application避免 React Flux 应用程序中受控输入的重新渲染
【发布时间】:2016-05-11 17:14:04
【问题描述】:

我的应用程序中有一个经典的 Flux 模式,使用 fluxible。输入的 value 与我的组件的 prop 相关联,它的 onChange 调用一个动作,该动作又更新一个 store,而 store 又将一个 prop 传递给我的组件:

class MyComponent extends React.Component {
  handleChange(e) {
    this.context.executeAction(persist, { value: e.target.value });
  }

  render() {
    return <input value={this.props.value} onChange={this.handleChange.bind(this)}/>;
  }
}

我遇到的问题是,当商店发出更改并且新值被传递到我的组件中时,这会导致它重新渲染,并且输入光标位置丢失(移动到最后)。

我知道我可以为我的组件创建一个自定义的shouldComponentUpdate 方法,但是这样做有点棘手,而且我认为这是一种非常频繁出现的模式,这绝对是乏味的。

是否有一种完善的模式来避免对受控输入进行重新渲染?

【问题讨论】:

  • 对我来说已经有一段时间了,但我记得我所有的表单都在管理自己的状态,以防止在用户编辑它时对其进行更改。也许您只能在用户输入不等于this.props.value 的内容时设置状态值。只是一个想法。
  • 感谢@JasonRice,我得出了非常相似的结论。

标签: javascript reactjs flux fluxible


【解决方案1】:

我发现ReactLink 的描述为处理这类事情提供了一个很好的模式。这是我想出的:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { value: props.value };
    this.handleChange = this.handleChange.bind(this);
  }

  componentWillReceiveProps(newProps) {
    // If in some cases you want to handle a new value prop, update state here
  }

  handleChange({ target: { value } }) {
    this.setState({ value });
    this.context.executeAction(persist, { value });
  }

  render() {
    return <input value={this.state.value} onChange={this.handleChange}/>;
  }
}

基本上,只需忽略那些说“如果您根据道具设置状态,那么您做错了”的人,并根据道具设置您的初始状态。此状态是您的输入现在用于其值的状态。然后,假设新的value 道具确实进来了,它们不会影响你的render 输出。如果您确实希望他们这样做,您可以将逻辑添加到 componentWillReceiveProps。例如,就我而言,我确实想更新输入,但前提是它没有聚焦:

componentWillReceiveProps({ value }) {
  if (!this.state.isFocused) {
    this.setState({ value });
  }
}

【讨论】:

  • 使用isFocused 的问题是用户将编辑输入然后转到下一个字段,只是为了撤消他们之前的工作,这会令人沮丧。如果是我,我会添加一个简单地清除状态或重新初始化它的重置按钮。 (我猜这假设有多个字段和一个提交按钮)
  • 这很好,@JasonRice。就我而言,这些外部道具更新来自一个同步过程,该过程在不可预测的时间从另一个来源提取数据。也许对这种情况的更好检查是仅在未输入内容的情况下替换内容。我开始意识到,可能没有万能的好方案,这就是为什么需要自定义 componentWillReceiveProps
猜你喜欢
  • 1970-01-01
  • 2018-12-16
  • 1970-01-01
  • 1970-01-01
  • 2020-12-21
  • 1970-01-01
  • 2018-12-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多