在React ES6中,为什么在输入一个字符后输入框会失去焦点?

235
在我的下面组件中,在键入字符后,输入字段会失去焦点。使用Chrome Inspector时,看起来整个表单在键入时被重新渲染,而不仅仅是输入字段的值属性。
我从eslint和Chrome Inspector都没有收到错误。
提交表单本身正常工作,实际输入字段也正常工作,当它位于渲染的返回值中或作为单独组件导入时,但在下面所编码的方式中却不行。
为什么会这样? 主页面组件
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as actionPost from '../redux/action/actionPost';
import InputText from './form/InputText';
import InputSubmit from './form/InputSubmit';

class _PostSingle extends Component {
    constructor(props, context) {
        super(props, context);
        this.state = {
            post: {
                title: '',
            },
        };
        this.onChange = this.onChange.bind(this);
        this.onSubmit = this.onSubmit.bind(this);
    }
    onChange(event) {
        this.setState({
            post: {
                title: event.target.value,
            },
        });
    }
    onSubmit(event) {
        event.preventDefault();
        this.props.actions.postCreate(this.state.post);
        this.setState({
            post: {
                title: '',
            },
        });
    }
    render() {
        const onChange = this.onChange;
        const onSubmit = this.onSubmit;
        const valueTitle = this.state.post.title;
        const FormPostSingle = () => (
            <form onSubmit={onSubmit}>
                <InputText name="title" label="Title" placeholder="Enter a title" onChange={onChange} value={valueTitle} />
                <InputSubmit name="Save" />
            </form>
        );
        return (
            <main id="main" role="main">
                <div className="container-fluid">
                    <FormPostSingle />
                </div>
            </main>
        );
    }
}

_PostSingle.propTypes = {
    actions: PropTypes.objectOf(PropTypes.func).isRequired,
};

function mapStateToProps(state) {
    return {
        posts: state.posts,
    };
}

function mapDispatchToProps(dispatch) {
    return {
        actions: bindActionCreators(actionPost, dispatch),
    };
}

export default connect(mapStateToProps, mapDispatchToProps)(_PostSingle);

文本输入组件

import React, { PropTypes } from 'react';

const InputText = ({ name, label, placeholder, onChange, value, error }) => {
    const fieldClass = 'form-control input-lg';
    let wrapperClass = 'form-group';
    if (error && error.length > 0) {
        wrapperClass += ' has-error';
    }
    return (
        <div className={wrapperClass}>
            <label htmlFor={name} className="sr-only">{label}</label>
            <input type="text" id={name} name={name} placeholder={placeholder} onChange={onChange} value={value} className={fieldClass} />
            {error &&
                <div className="alert alert-danger">{error}</div>
            }
        </div>
    );
};

InputText.propTypes = {
    name: PropTypes.string.isRequired,
    label: PropTypes.string.isRequired,
    placeholder: PropTypes.string.isRequired,
    onChange: PropTypes.func.isRequired,
    value: PropTypes.string,
    error: PropTypes.string,
};

InputText.defaultProps = {
    value: null,
    error: null,
};

export default InputText;

提交按钮组件

import React, { PropTypes } from 'react';

const InputSubmit = ({ name }) => {
    const fieldClass = 'btn btn-primary btn-lg';
    return (
        <input type="submit" value={name} className={fieldClass} />
    );
};

InputSubmit.propTypes = {
    name: PropTypes.string,
};

InputSubmit.defaultProps = {
    name: 'Submit',
};

export default InputSubmit;

1
感谢这个问题,它是从 https://www.paypal-community.com/t5/Managing-Account/Enter-your-code-page-input-looses-focus/m-p/2876787/highlight/true#M21997 链接过来的,因为这可能与为什么 PayPal 的双重认证开始失去焦点有关... - Tobias Kienzler
34个回答

0

我没有权限进行评论,那就只能回答了。我遇到过类似的问题,Alex Yan 的回答是正确的。

具体来说,我遇到了这个函数

const DisplaySearchArea =()=>{return (arrayOfSearchFieldNames.map((element, index)=>{return(<div key ={index} className = {inputFieldStyle}><input  placeholder= {arrayOfPlaceholders[index]} type="text" className='border-0'
value={this.state[element]}
onChange={e => {this.setState({ [element]: e.target.value }); console.log(e.target)}}
onMouseEnter={e=>e.target.focus()}/></div>)}))}

当渲染为<DisplaySearchArea />时,在FF中表现良好,但在Chrome中不行。当以{...}的形式呈现时,两者都可以正常工作。虽然这段代码看起来不太美观,但它是有效的。我已经被告知有过度使用lambda表达式的倾向。


0

谢谢,Alex。这样我解决了我的问题:

constructor(props, context) {
    ...
    this.FormPostSingle = this.FormPostSingle.bind(this);
}
FormPostSingle() {
        const onChange = this.onChange;
        const onSubmit = this.onSubmit;
        const valueTitle = this.state.post.title;
        return (
        <form onSubmit={onSubmit}>
                <InputText name="title" label="Title" placeholder="Enter a title" onChange={onChange} value={valueTitle} />
                <InputSubmit name="Save" />
            </form>        );
}
render() {
    let FormPostSingle = this.FormPostSingle
    return...
}

0

我刚遇到了同样的问题。我想要实现的是在登录过程中让用户插入OTP,但问题在于我通过电子邮件将PIN发送给用户,将他们移动到下一页并使用setInterval开始倒计时,这就是导致我的问题的原因,因为它更新了this.setState({counter:counter++}),一旦发生这种情况,应用程序会重新渲染,由于我的表单在render:function()中,所以它也会被重新渲染并清除OTP字段,使用户需要重新开始输入PIN。

所以我做的是像这样创建我的输入字段:

<input name="otp" value={this.state.counter} onChange="updateValue(e)"/>

然后让我的updateValue函数进行更新

function updateValue(e){
    this.setState({counter:e.currentTarget.value})
}

意思是我的计时器会继续重置状态甚至重新渲染,但由于输入字段上的值保持不变,因此不会丢失。

我知道这可能已经解决了我的问题,虽然我的问题有点不同,但逻辑基本相同,因为它解决了相同的问题。


0
基本上,这种错误是由于“onChange”事件引起的。
  1. 如果您使用普通的HTML,则将autoFocus属性设置为标签

     <input placeholder="搜索.."
            value={searchTerm}
            onChange={(e) => { 
              setSerachTerm(e.target.value.trim()) 
            }}
            autoFocus={true} />
    
  2. 如果您使用其他库,如React中的mui UI,请查看文档并设置相应的autoFocus属性


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接