2017-03-03 68 views
5

在下面的组件中,输入字段后输入字段丢失焦点。在使用Chrome的Inspector时,看起来整个表单在输入时将被重新渲染,而不仅仅是输入字段的值属性。在React ES6中,输入字符后为什么会丢失焦点?

我从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; 

回答

0

当你输入一个字符时,你的表格会被重新渲染,因为你有一个onChange方法,它改变了状态。每次状态变化都会导致表单重新渲染,这就是为什么输入法会失去焦点。

由于您正在使用redux,最好的方法是将帖子标题值存储在redux对象中。此外,你可能想看看你的表格使用redux-form

要获得没有re-rendering的输入值,您需要使用refs

2

发生了什么事是这样的:

当你的onChange事件触发,回调调用的setState新标题值,该值被传递给你的文本字段作为道具。那时,React重新渲染它,这就是为什么你失去了焦点。

我的第一个建议是提供你的组件键,特别是表单和输入本身。密钥允许React通过渲染保留组件的标识。

-1

那是因为你呈现形式在函数内部渲染()。

每当你的状态/道具改变时,函数就会返回一个新的窗体。它导致你失去焦点。

尝试把什么是函数内部到您的直接呈现。

 <main id="main" role="main"> 
      <div className="container-fluid"> 
       <FormPostSingle /> 
      </div> 
     </main> 

====>

 <main id="main" role="main"> 
      <div className="container-fluid"> 
       <form onSubmit={onSubmit}> 
        <InputText name="title" label="Title" placeholder="Enter a title" onChange={onChange} value={valueTitle} /> 
        <InputSubmit name="Save" /> 
       </form> 
      </div> 
     </main>