我有一组具有defaultValue设置的React输入元素。使用onBlur事件更新值。
我还在页面上有另一个操作来更新这些输入元素中的所有值。当发生这种情况时,有没有办法强制做出反应以呈现新的违约值?
我不能轻易使用onChange,因为它会触发过早的重新渲染(输入包含一个显示顺序值,而过早的重新渲染会移动它们)。
我可以创建一个重复状态,一个用于仅使用onBlur更新的实际值,另一个用于在编辑时更新input元素中的值。这远非理想。重置默认值会简单得多。
答案 0 :(得分:2)
如https://stackoverflow.com/a/21750576/275501中所述,您可以为状态控制的渲染组件的外部元素指定一个键。这意味着您有一个“切换”来完全重置组件,因为React会考虑一个新键来指示一个全新的元素。
e.g。
class MyComponent extends React.Component {
constructor() {
super();
this.state = {
key: Date.now(),
counter: 0
};
}
updateCounter() {
this.setState( { counter: this.state.counter + 1 } );
}
updateCounterAndReset() {
this.updateCounter();
this.setState( { key: Date.now() } );
}
render() { return (
<div key={this.state.key}>
<p>
Input with default value:
<input type="text" defaultValue={Date.now()} />
</p>
<p>
Counter: {this.state.counter}
<button onClick={this.updateCounter.bind( this )}>Update counter</button>
<button onClick={this.updateCounterAndReset.bind( this )}>Update counter AND reset component</button>
</p>
</div>
); }
}
ReactDOM.render( <MyComponent />, document.querySelector( "#container" ) );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container" />
答案 1 :(得分:0)
我已经通过同时使用onBlur和onChange解决了这个问题,并且只跟踪状态中当前活动的输入元素。
如果有办法重置模块以便重新显示新的默认值,那么我会将其标记为正确。
state = {
inFocusIndex: null,
inFocusDisplayOrder: 0,
};
onOrderBlur() {
const productRow = this.props.products[this.state.inFocusIndex];
const oldDisplayORder = productRow.displayOrder;
// This can change all the display order values in the products array
this.props.updateDisplayOrder(
this.props.groupId,
productRow.productGroupLinkId,
oldDisplayORder,
this.state.inFocusDisplayOrder
);
this.setState({ inFocusIndex: null });
}
onOrderChanged(index, event) {
this.setState({
inFocusIndex: index,
inFocusDisplayOrder: event.target.value,
});
}
在渲染功能中:
{this.props.products.map((row, index) => {
return (
<input
type="text"
value={index === this.state.inFocusIndex ? this.state.inFocusDisplayOrder : row.displayOrder}
className={styles.displayOrder}
onChange={this.onOrderChanged.bind(this, index)}
onBlur={this.onOrderBlur.bind(this)} />
);
})}