我的应用程序中有一个经典的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
方法,但这样做有点棘手,而且我认为这是一种非常频繁的模式,这显然很乏味。
是否有完善的模式来避免重新渲染受控输入?
答案 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 });
}
}