Javascript 输入在键入时失去焦点

Javascript 输入在键入时失去焦点,javascript,reactjs,Javascript,Reactjs,我在使用输入时遇到问题。。。我有两个输入:一个有自动对焦,另一个没有。但是,当我输入第二个输入时,它会失去焦点,焦点会返回到第一个输入 我读过React在我键入内容时会重新加载我的组件。我试着放一个关键的道具等,但没有任何效果 在我的表单(一个名为Signup的组件)中,我有以下内容: import React from 'react' import Input from '../../components/Input' import styles from './styles.scss' c

我在使用输入时遇到问题。。。我有两个输入:一个有自动对焦,另一个没有。但是,当我输入第二个输入时,它会失去焦点,焦点会返回到第一个输入

我读过React在我键入内容时会重新加载我的组件。我试着放一个关键的道具等,但没有任何效果

在我的表单(一个名为Signup的组件)中,我有以下内容:

import React from 'react'
import Input from '../../components/Input'
import styles from './styles.scss'

class Signup extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      name: '',
      email: '',
    }
  }

  onSignup (e, userData) {
    e.preventDefault()
    this.props.onSignup(userData)
  }

  render () {
    return (
      <main className={styles.wrapper}>
        <div className={styles.formSide}>
          <h1>SIGNUP</h1>

          <Input
            id="name"
            label="Name"
            onChange={e => this.setState({ name: e.target.value })}
            autofocus={true}
          />
          <Input
            id="email"
            label="E-mail"
            onChange={e => this.setState({ email: e.target.value })}
          />
        </div>
      </main>
    )
  }
}

Signup.propTypes = {
  onSignup: React.PropTypes.func.isRequired
}

export default Signup
从“React”导入React
从“../../components/Input”导入输入
从“./styles.scss”导入样式
类注册扩展了React.Component{
建造师(道具){
超级(道具)
此.state={
名称:“”,
电子邮件:“”,
}
}
onSignup(e,用户数据){
e、 预防默认值()
this.props.onSignup(userData)
}
渲染(){
返回(
报名
this.setState({name:e.target.value})}
自动对焦={true}
/>
this.setState({email:e.target.value})
/>
)
}
}
Signup.propTypes={
onSignup:React.PropTypes.func.isRequired
}
导出默认注册
我的组件输入有以下代码:

import React, { PropTypes } from 'react'
import MaskedInput from 'react-maskedinput'
import styles from './styles.scss'

function Input (props) {
  let iconComp

  if (props.icon) {
    iconComp = (<img src={props.icon} alt="Icon" />)
  }

  let input = ''

  if (props.type === 'date') {
    input = (
      <MaskedInput
        ref={inp => inp && props.autofocus && inp.focus()}
        onChange={props.onChange}
        mask="11/11/1111"
        placeholder={props.placeholder}
        className={styles.input}
      />
    )
  } else {
    input = (
      <input
        ref={inp => inp && props.autofocus && inp.focus()}
        onChange={props.onChange}
        id={props.id}
        placeholder={props.placeholder}
        type={props.type}
        className={styles.input}
      />
    )
  }

  return (
    <div className={styles.wrapper}>
      <label htmlFor={props.id} className={styles.label}>{props.label}</label>
      <br />
      {input}
      {props.error &&
        <span className={styles.error}>
          {props.errorMessage}
        </span>
      }
      {iconComp}
    </div>
  )
}

Input.propTypes = {
  id: PropTypes.string.isRequired,
  label: PropTypes.string.isRequired,
  icon: PropTypes.string,
  placeholder: PropTypes.string,
  type: PropTypes.string,
  autofocus: PropTypes.bool,
  onChange: PropTypes.func.isRequired,
  error: PropTypes.bool,
  errorMessage: PropTypes.string
}

Input.defaultProps = {
  icon: '',
  placeholder: '',
  type: 'text',
  autofocus: false,
  error: false,
  errorMessage: ''
}

export default Input
import React,{PropTypes}来自“React”
从“react MaskedInput”导入MaskedInput
从“./styles.scss”导入样式
功能输入(道具){
让我进来
如果(道具图标){
iconComp=()
}
让输入=“”
如果(props.type=='date'){
输入=(
inp&&props.autofocus&&inp.focus()}
onChange={props.onChange}
mask=“11/11/1111”
占位符={props.placeholder}
className={styles.input}
/>
)
}否则{
输入=(
inp&&props.autofocus&&inp.focus()}
onChange={props.onChange}
id={props.id}
占位符={props.placeholder}
类型={props.type}
className={styles.input}
/>
)
}
返回(
{props.label}

{input} {props.error&& {props.errorMessage} } {iconComp} ) } Input.propTypes={ id:PropTypes.string.isRequired, 标签:PropTypes.string.isRequired, 图标:PropTypes.string, 占位符:PropTypes.string, 类型:PropTypes.string, 自动对焦:PropTypes.bool, onChange:PropTypes.func.isRequired, 错误:PropTypes.bool, errorMessage:PropTypes.string } Input.defaultProps={ 图标:“”, 占位符:“”, 键入:“文本”, 自动对焦:错误, 错误:false, 错误消息:“” } 导出默认输入

如何解决此问题?

问题是每次渲染输入时,都会为
ref
创建并调用新的线条箭头函数。因此它每次执行
inp.focus()
。避免这种情况的一种方法是使用类组件并将
ref
回调方法定义为类函数

class Input extends React.Component {

  refCallback(inp){
    if(this.props.autofocus) inp.focus();
  }

  render(){
    let input = ''

    if (this.props.type === 'date') {
      input = (
        <MaskedInput
          ref={this.refCallback}
          onChange={this.props.onChange}
          mask="11/11/1111"
          placeholder={this.props.placeholder}
        />
      )
    } else {
      input = (
        <input
          ref={this.refCallback}
          onChange={this.props.onChange}
          id={this.props.id}
          placeholder={this.props.placeholder}
          type={this.props.type}
        />
      )
    }

    return (
      <div>
        <label htmlFor={this.props.id}>{this.props.label}</label>
        <br />
        {input}
      </div>
    )
  }
}

export default Input
类输入扩展了React.Component{
REF回调(inp){
if(this.props.autofocus)inp.focus();
}
render(){
让输入=“”
如果(this.props.type=='date'){
输入=(
)
}否则{
输入=(
)
}
返回(
{this.props.label}

{input} ) } } 导出默认输入
更新的代码笔:


(我以前的代码有一些问题,因为我无法测试它。但现在我更新了代码,它可以正常工作)

因此,一个简单的解决方案是增强注册组件,使其具有另一个名为nameAutoFocus的属性,并将其初始化为true。使用此属性可设置自动聚焦布尔值。然后将方法componentDidMount和内部集合名称AutoFocus添加到false

    class Signup extends React.Component {
      constructor (props) {
        super(props)
        this.state = {
          name: '',
          email: '',
        }

        this.nameAutoFocus = true; //new
      }

      onSignup (e, userData) {
        e.preventDefault()
        this.props.onSignup(userData)
      }

       //new
      componentDidMount() {
        this.nameAutoFocus = false;
      }

      render () {
        return (
          <main>
            <div>
              <h1>SIGNUP</h1>

              <Input
                id="name"
                label="Name"
                onChange={e => this.setState({ name: e.target.value })}
                autofocus={this.nameAutoFocus}
              />
              <Input
                id="email"
                label="E-mail"
                onChange={e => this.setState({ email: e.target.value })}
              />
            </div>
          </main>
        )
      }
    }
类注册扩展了React.Component{
建造师(道具){
超级(道具)
此.state={
名称:“”,
电子邮件:“”,
}
this.nameAutoFocus=true;//新建
}
onSignup(e,用户数据){
e、 预防默认值()
this.props.onSignup(userData)
}
//新的
componentDidMount(){
this.nameautoccus=false;
}
渲染(){
返回(
报名
this.setState({name:e.target.value})}
自动对焦={this.nameAutoFocus}
/>
this.setState({email:e.target.value})
/>
)
}
}
这是因为nameAutoFocus的初始值被传递给给予它焦点的输入,然后componentDidMount将运行并将其设置为false,这样下次状态更改时,它就不会将autofocus属性设置为true。这本质上是在最初渲染时只给它一次焦点

代码笔:
别忘了单击“运行”。

你能把它放在小提琴或弹琴中吗?如果你做了演示,我想我有一个解决方案,但我无法测试它。谢谢,我为你准备了一个简单的解决方案。很抱歉我最后的评论,但它起了作用!我将做一个演示,@floorMy以前的代码有一些问题,因为我无法测试它。但是现在我已经更新了代码,它可以工作了。我还包括了更新的代码笔。@TharakaWijebandara此解决方案对我不起作用,在代码笔中也不起作用。@我很惊讶。这对我很有用。让我们看看莱昂内罗有什么要说的。这个解决方案对我有效:D,但@floor的解决方案要简单一点。