2017-03-03 1 views
5

In meiner unten stehenden Komponente verliert das Eingabefeld den Fokus nach der Eingabe eines Zeichens. Bei der Verwendung des Informationsfensters von Chrome sieht es so aus, als ob das gesamte Formular neu gerendert wird und nicht nur das Wertattribut des Eingabefelds beim Tippen.In React ES6, warum verliert das Eingabefeld den Fokus nach der Eingabe eines Zeichens?

Ich bekomme keine Fehler von entweder Eslint noch Chrome Inspector.

Das Senden des Formulars selbst funktioniert genauso wie das eigentliche Eingabefeld, wenn es entweder in der Render-Rückgabe oder beim Import als separate Komponente liegt, aber nicht in der Art, wie ich es unten codiert habe.

Warum ist das so?

Hauptseite Komponente

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); 

Texteingabekomponente

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; 

Absenden Button-Komponente

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; 

Antwort

0

Ihr Formular wird neu gerendert, wenn Sie ein Zeichen eingeben, weil Sie eine onChange Methode haben, die den Status ändert. Jede Statusänderung bewirkt, dass das Formular neu gerendert wird. Daher verliert die Eingabemethode den Fokus.

Da Sie redux verwenden, wäre der beste Weg, den Post-Titel-Wert im redux-Objekt zu speichern. Vielleicht möchten Sie auch einen Blick auf redux-form für Ihr Formular werfen.

Um den Wert der Eingabe ohne die re-rendering zu erhalten, müssen Sie refs verwenden.

2

Was geschieht, ist dies:

Wenn Ihr onChange Ereignis ausgelöst wird, der Rückruf ruft setState mit dem neuen Titel Wert, der als Stütze zu Ihrem Textfeld übergeben wird. An diesem Punkt macht React es neu, weshalb Sie den Fokus verlieren.

Mein erster Vorschlag wäre, Ihre Komponenten Schlüssel, insbesondere die Form und die Eingabe selbst zu bieten. Mit Keys kann React die Identität von Komponenten durch Rendervorgänge beibehalten.

-1

ist es, weil Sie das Formular in einer Funktion innerhalb render() rendern.

Jedes Mal, wenn sich Ihr Status/Prop ändert, gibt die Funktion ein neues Formular zurück. es hat dich dazu gebracht, den Fokus zu verlieren.

Versuchen Sie, das, was in der Funktion enthalten ist, direkt in Ihren Render zu setzen.

 <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> 
Verwandte Themen