我有以下代码,这会导致在公司密码字段中按下键后焦点丢失。由于setState
,探索表明表格正在重新呈现,但我不确定为什么或如何修复。
import React from 'react';
import LocalizedStrings from 'react-localization';
let strings = new LocalizedStrings({
// code omitted
});
class ResetPasswordForm extends React.Component {
constructor (props) {
super(props);
this.state = {
key: this.props.key,
password: '',
passwordConfirm: ''
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
}
handleSubmit(event) {
event.preventDefault();
// TODO
}
renderField(field) {
const name = field.name;
const id = field.id || name;
const label = strings[name];
const fieldType = field.type || 'text';
const placeholder = strings[name + '-placeholder'];
// TODO
let touched;
let error;
return <div className="form-group">
<label htmlFor={id}>{label}:</label>
<input id={id} type={fieldType} placeholder={placeholder} name={name} onChange={this.handleChange}
value={this.state[name]}
className="form-control"/> {touched && error && <div className="error bg-warning">{error}</div>}
</div>
}
render() {
const Field = this.renderField.bind(this);
return (
<div>
<h2>{strings['title']}</h2>
<form onSubmit={this.handleSubmit} >
{this.props.statusText && <div className='alert alert-info'>
{this.props.statusText}
</div>}
<Field
name="password"
type="password"
/>
<Field
name="passwordConfirm"
type="password"/>
<div className="form-group">
<input
type="submit"
name="Submit"
defaultValue={strings['submit']}
/>
</div>
</form>
</div>
)
}
}
编辑:进一步的实验表明,“字段”行导致了问题,并用以下内容替换它们可以解决问题:
{this.renderField({
name: "password",
type: "password"
})}
{this.renderField({
name: "passwordConfirm",
type: "password"
})}
或者,在构造函数中我可以这样做:
this.renderField = this.renderField.bind(this);
然后在渲染函数中我可以做到:
const Field = this.renderField;
虽然这些方法有效,但我不确定React的变更罪的确切影响。如果有人能解释,我们将不胜感激。
答案 0 :(得分:0)
我认为这是错误:
const Field = this.renderField.bind(this);
renderField(field)接受对象参数(字段),你永远不会传递它。所以你需要传递它
const Field = this.renderField.bind(this, { name: "password", type: "password"});
答案 1 :(得分:0)
每次执行render
时,您都会使用this.renderField.bind(this)
生成新的功能组件。在这种情况下,React的协调算法会将此视为差异,整个子树将从头开始呈现。
来自docs:
不同类型的元素
每当根元素具有不同类型时,React将会拆除 旧树并从头开始构建新树。从去到 或者来自,或来自 - 任何 这些将导致完全重建。
这是一个DevTools元素检查器的屏幕截图,它说明了两种情况下的DOM更新