Javascript 输入react表单会导致焦点丢失和重新渲染

Javascript 输入react表单会导致焦点丢失和重新渲染,javascript,reactjs,Javascript,Reactjs,我有下面的代码,这会导致在“确定密码”字段中按下一个键时焦点丢失。探索表明,由于setState的原因,表单正在重新呈现,但我不确定为什么或如何修复 import React from 'react'; import LocalizedStrings from 'react-localization'; let strings = new LocalizedStrings({ // code omitted }); class ResetPasswordForm extends R

我有下面的代码,这会导致在“确定密码”字段中按下一个键时焦点丢失。探索表明,由于
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 = this.renderField.bind(this);
const Field = this.renderField;
然后在渲染函数中,我可以执行以下操作:

this.renderField = this.renderField.bind(this);
const Field = this.renderField;

虽然这些方法可行,但我不确定变化对反应的确切影响。如果有人能解释,我们将不胜感激。

我想这里是错误:

const Field = this.renderField.bind(this);
renderField(field)接受对象参数(field),并且您永远不会传递它。所以你需要通过考试

const Field = this.renderField.bind(this, { name: "password", type: "password"});

我认为这是一个错误:

const Field = this.renderField.bind(this);
renderField(field)接受对象参数(field),并且您永远不会传递它。所以你需要通过考试

const Field = this.renderField.bind(this, { name: "password", type: "password"});

每次执行
render
时,都会使用
this.renderField.bind(this)
生成新的函数组件。在这种情况下,React的协调算法会将此视为差异,整个子树将从头开始渲染

发件人:

不同类型的元素

只要根元素有不同的类型,React就会被删除 老树,从头开始建新树。从到 ,或从至,或从至任何 其中之一将导致全面重建

下面是DevTools元素检查器的屏幕盖,它演示了这两种情况下的DOM更新

  • 原始(在每次渲染时生成字段)
    您可以看到,
    节点被折叠,从头开始渲染=>焦点丢失。
  • 已修复(
    this.renderField({…})
    已使用)
    只有
    “value”
    字段被更新,DOM的其余部分完好无损=>焦点被保留

  • 每次执行
    render
    时,都会使用
    this.renderField.bind(this)
    生成新的函数组件。在这种情况下,React的协调算法会将此视为差异,整个子树将从头开始渲染

    发件人:

    不同类型的元素

    只要根元素有不同的类型,React就会被删除 老树,从头开始建新树。从到 ,或从至,或从至任何 其中之一将导致全面重建

    下面是DevTools元素检查器的屏幕盖,它演示了这两种情况下的DOM更新

  • 原始(在每次渲染时生成字段)
    您可以看到,
    节点被折叠,从头开始渲染=>焦点丢失。
  • 已修复(
    this.renderField({…})
    已使用)
    只有
    “value”
    字段被更新,DOM的其余部分完好无损=>焦点被保留

  • 这并不能真正解释发生了什么。在挖掘过程中,我发现了两种备选方案(见问题),但我不确定自己是否完全理解它们为什么有效,除了它们确实有效之外。这并不能真正解释发生了什么。在挖掘过程中,我发现了两种备选方案(见问题),但我不确定自己是否完全理解它们为什么有效,除了它们确实有效之外。