【发布时间】:2019-03-18 03:02:54
【问题描述】:
我目前正在使用 Office UI 结构中的 TextField 并使用 onChanged 属性来分配我的道具,以响应输入的值,类似于他们的GitHub example。
但是,对于每个输入的元素都会调用事件处理程序。仅当用户完成输入整个文本(例如焦点关闭等)时,如何才能调用事件处理程序(this._onChange)?
我猜这会比在输入每个字母时记录事件更有效。
新的反应。感谢您的帮助!
【问题讨论】:
我目前正在使用 Office UI 结构中的 TextField 并使用 onChanged 属性来分配我的道具,以响应输入的值,类似于他们的GitHub example。
但是,对于每个输入的元素都会调用事件处理程序。仅当用户完成输入整个文本(例如焦点关闭等)时,如何才能调用事件处理程序(this._onChange)?
我猜这会比在输入每个字母时记录事件更有效。
新的反应。感谢您的帮助!
【问题讨论】:
您可以使您的状态和 UI 保持同步,但使用您自己的延迟验证错误检查功能来检查值是好/坏和/或您是否想做一些事情,例如仅在之后基于值进行日志记录一定的时间过去了。下面复制了本页的一些示例以供快速参考 - 您可以在“_getErrorMessage”函数 (https://github.com/OfficeDev/office-ui-fabric-react/blob/master/packages/office-ui-fabric-react/src/components/TextField/examples/TextField.ErrorMessage.Example.tsx) 中做任何您想做的事情:
<TextField
label="Deferred string-based validation"
placeholder="Validates after user stops typing for 2 seconds"
onGetErrorMessage={this._getErrorMessage}
deferredValidationTime={2000}
/>
<TextField
label="Validates only on focus and blur"
placeholder="Validates only on input focus and blur"
onGetErrorMessage={this._getErrorMessage}
validateOnFocusIn
validateOnFocusOut
/>
【讨论】:
你可以考虑使用 React 的 onBlur 属性,当输入失去焦点时会调用它。这是一个示例 Codepen,其中 window.alert 是 <TextField> 组件失去焦点时的当前值:https://codepen.io/kevintcoughlin/pen/zmdaJa?editors=1010。
代码如下:
const {
Fabric,
TextField
} = window.Fabric;
class Content extends React.Component {
public render() {
return (
<Fabric>
<TextField onBlur={this.onBlur} />
</Fabric>
);
}
private onBlur(ev: React.FocusEvent<HTMLInputElement>) {
window.alert(ev.target.value);
}
}
ReactDOM.render(
<Content />,
document.getElementById('content')
);
希望对您有所帮助。
参考文献
【讨论】:
这更像是 React 使用输入 onChange 事件的一般方式。使用 React,您希望将输入的值保存在某处的状态中,无论是组件状态还是像 Redux 这样的全局存储。您的状态和 UI 应该始终保持同步。因此,onChange 事件会针对每个输入/删除的字符触发,以便您可以更新该状态以反映新值。以这种方式编写的输入称为受控组件,您可以在https://reactjs.org/docs/forms.html 阅读有关它们的更多信息并查看一些示例。
话虽如此,您可以检测到用户何时使用onBlur 事件离开输入,但我不建议使用它来使用该值更新状态,因为您会看到受控组件将读取 -仅当您不更新 onChange 事件中的状态时。您将不得不使用不受控制的组件,通常将初始值设置为 defaultValue 而不是 value,这会让您自己变得更加困难。
// CORRECT IMPLEMENTATION
class ControlledForm extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
name: 'example'
};
this.handleNameChange = this.handleNameChange.bind(this);
}
handleNameChange(e) {
this.setState({
name: e.target.value
});
}
render() {
return (
<div>
<h1>Controlled Form</h1>
<input type="text" value={this.state.name} onChange={this.handleNameChange} />
<p>{this.state.name}</p>
</div>
);
}
}
// INPUT DOES NOT WORK
class BuggyUncontrolledForm extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
name: 'example'
};
}
render() {
return (
<div>
<h1>Buggy Uncontrolled Form</h1>
<input type="text" value={this.state.name} />
<p>{this.state.name}</p>
</div>
);
}
}
// NOT RECOMMENDED
class UncontrolledForm extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
name: 'example'
};
this.handleNameChange = this.handleNameChange.bind(this);
}
handleNameChange(e) {
this.setState({
name: e.target.value
});
}
render() {
return (
<div>
<h1>Uncontrolled Form</h1>
<input type="text" defaultValue={this.state.name} onBlur={this.handleNameChange} />
<p>{this.state.name}</p>
</div>
);
}
}
ReactDOM.render(
<div>
<ControlledForm />
<BuggyUncontrolledForm />
<UncontrolledForm />
</div>
, document.getElementById('root'));
<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="root"></div>
【讨论】: