避免在React Flux应用程序中对受控输入进行重新渲染

时间:2016-02-02 18:34:06

标签: javascript reactjs flux fluxible

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

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方法,但这样做有点棘手,而且我认为这是一种非常频繁的模式,这显然很乏味。

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

1 个答案:

答案 0 :(得分: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 });
  }
}