2017-03-03 82 views
5

W poniższym komponencie pole wprowadzania traci ostrość po wpisaniu znaku. Podczas korzystania z Inspektora Chrome wygląda to tak, jakby cały formularz był ponownie renderowany zamiast tylko wartości atrybutu pola wejściowego podczas pisania.W React ES6, dlaczego pole wprowadzania traci ostrość po wpisaniu znaku?

Nie otrzymuję żadnych błędów ani od eslint, ani od Inspektora Chrome.

Przesłanie formularza samo w sobie działa tak samo jak rzeczywiste pole wejściowe, gdy znajduje się ono w powrocie renderu lub podczas importowania jako oddzielny komponent, ale nie w sposobie, w jaki mam to zakodowane poniżej.

Dlaczego tak się dzieje?

Page główny składnik

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

Wejście komponentowe Tekst

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; 

Prześlij Przycisk Komponent

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; 

Odpowiedz

0

Twój formularz jest ponownie wysyłany po wpisaniu znaku, ponieważ masz metodę onChange, która zmienia stan. Każda zmiana stanu powoduje ponowne wysłanie formularza, dlatego metoda wprowadzania traci ostrość.

Ponieważ używasz redux, najlepszym sposobem byłoby przechowywanie wartości tytułu po wpisie w obiekcie redux. Możesz również rzucić okiem na użycie formularza redux-form.

Aby uzyskać wartość sygnału wejściowego bez parametru re-rendering, należy użyć wartości refs.

2

Co się dzieje jest to:

Gdy Zdarzenie onChange, callback zwraca setstate z nową wartością tytuł, który zostanie przeniesiony do pola tekstowego jako rekwizyt. W tym momencie React renderuje to od nowa, dlatego tracisz koncentrację.

Moja pierwsza sugestia to dostarczenie kluczy komponentów, szczególnie formularza i samego wejścia. Klucze pozwalają Reactowi zachować tożsamość komponentów poprzez rendery.

-1

dzieje się tak, ponieważ renderujesz formularz w funkcji wewnątrz render().

Za każdym razem, gdy zmienia się stan/podpora, funkcja zwraca nowy formularz. to spowodowało, że straciłeś ostrość.

Spróbuj umieścić to, co znajduje się wewnątrz funkcji w swoim renderingu.

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