2015-06-09 12 views
10

dieses Beispiel vor:Reagieren - Eingang default ändern, indem Requisiten

var Field = React.createClass({ 
    render: function() { 
     // never renders new value... 
     return (
      <div> 
       <input type="text" defaultValue={this.props.value || ''} /> 
      </div> 
     ); 
    } 
}); 

var App = React.createClass({ 
    getInitialState: function() { 
     return {value: 'Hello!'}; 
    }, 

    changeTo: function (str) { 
     this.setState({value: str}); 
    }, 

    render: function() { 
     return (
      <div> 
       <Field value={this.state.value} /> 
       <button onClick={this.changeTo.bind(null, 'Whyyyy?')}>Change to "Whyyyy?"</button> 
       <button onClick={this.changeTo.bind(null, void 0)}>Change to undefined</button> 
      </div> 
     ); 
    } 
}); 

React.render(
    <App />, 
    document.getElementById('app') 
); 

Ich möchte Wert zu übergeben in defaultValue als Stütze der stummen Eingabekomponente. Es wird jedoch nie wieder gerendert.

+0

Lesen Sie https://facebook.github.io/react/docs/forms.html#advanced-topics, warum dies geschieht. –

+0

Mögliches Duplikat von [React input defaultValue wird nicht mit state aktualisiert] (http://stackoverflow.com/questions/30146105/react-input-defaultvalue-doesnt-update-with-state) – Manolo

Antwort

3

Ich bin ziemlich sicher, dass dies mit Controlled vs. Uncontrolled inputs zu tun hat.

Wenn ich richtig verstehe, da Ihre <input> Unkontrollierte ist (nicht definiert ein value Attribut), dann wird der Wert immer auf den Wert beheben, dass es mit initialisiert wird. In diesem Fall Hello!.

Um dieses Problem zu überwinden, können Sie ein value Attribut hinzufügen und es während der onChange:

var Field = React.createClass({ 
     render: function() { 
      // never renders new value... 
      return (
       <div> 
        <input type="text" defaultValue={this.props.default || ''} value={this.props.value} /> 
       </div> 
     ); 
     } 
    }); 

Here is a plunker die Änderung zeigt.

+0

Ist dies der sauberste Weg zur Lösung unkontrollierte Eingänge? Außerdem sehe ich in Ihrem Beispiel keine 'onChange' Funktion. – JohnnyQ

+0

@JohnnyQ unkontrollierte Komponenten benötigen kein 'onChange'. Normalerweise wird der Wert mit einem 'ref' extrahiert. –

+0

Splendid, es gibt einen Fehler mit Werteinstellung und anderen Schlüsseln wie onKeyUp/onKeyPress, also wenn U unter bestimmten Umständen das onKeyUp-Ereignis für ex benötigen, sollten Sie OnChange für dieselbe Funktion festlegen, andernfalls wird das Wertattribut nicht sein aktualisiert. –

10

defaultValue funktioniert nur für die Anfangslast. Danach wird es nicht aktualisiert. Sie müssen den Zustand für Sie Feld Komponente erhalten:

var Field = React.createClass({ 
    //transfer props to state on load 
    getInitialState: function() { 
     return {value: this.props.value}; 
    }, 
    //if the parent component updates the prop, force re-render 
    componentWillReceiveProps: function(nextProps) { 
     this.setState({value: nextProps.value}); 
    }, 
    //re-render when input changes 
    _handleChange: function (e){ 
     this.setState({value: e.target.value}); 
    }, 
    render: function() { 
     // render based on state 
     return (
      <div> 
       <input type="text" onChange={this._handleChange} 
            value={this.state.value || ''} /> 
      </div> 
     ); 
    } 
}); 
0

ich auch mit diesem Problem konfrontiert, was ich tat, war manuell den Eingangswert zu aktualisieren, wenn die Requisiten Änderung hat. Fügen Sie diese auf Ihrem Feld reagieren Klasse:

componentWillReceiveProps(nextProps){ 
    if(nextProps.value != this.props.value) { 
     document.getElementById(<element_id>).value = nextProps.value 
    } 
} 

Sie müssen nur ein id-Attribut zu Ihrem Element hinzufügen, so dass es lokalisiert werden kann.

+1

Das bricht die React-Philosophie Ich denke, – David

0

Die Frage ist hier:

onClick={this.changeTo.bind(null, 'Whyyyy?')} 

Ich bin neugierig, warum Sie auf null binden.

Sie möchten an 'this' binden, damit changeTo in diesem Objekt setState setzt.

Versuchen Sie, diese

<button onClick={this.changeTo.bind(this, 'Whyyyy?')}>Change to "Whyyyy?"</button> 
<button onClick={this.changeTo.bind(this, void 0)}>Change to undefined</button> 

In Javascript, wenn eine Funktion aufgerufen wird, seine im Rahmen genannt, woher es genannt wurde, nicht dort, wo es geschrieben wurde (ich weiß, scheint unlogisch). Um sicherzustellen, dass es in dem Kontext aufgerufen wird, in dem Sie es schreiben, müssen Sie ".bind (this)" eingeben.

Um mehr über die Bindung und Funktionsumfang zu lernen, es gibt viele Online-tutes, (etwas viel besser als andere) - Du diese: http://ryanmorr.com/understanding-scope-and-context-in-javascript/

I Dev-Tool der Reaktion auch, wenn Sie empfehlen sind mit Firefox oder Chrom, auf diese Weise Sie in der Lage gewesen wären, dass state.message zu sehen war nicht zu ändern: wird für ein Formular auf Anfangslast https://facebook.github.io/react/blog/2015/09/02/new-react-developer-tools.html

25

Als vorherige Antwort erwähnt, defaultValue nur gesetzt. Danach wird es nicht "natürlich" aktualisiert, da nur der ursprüngliche Standardwert festgelegt werden sollte.

Sie können dieses Problem umgehen, wenn Sie benötigen ein key an die Wrapper-Komponente, indem, wie auf Ihrer Field oder App Komponente, wenn auch in praktischen Umständen, ist es wahrscheinlich ein form Komponente sein würde. Eine gute key wäre ein eindeutiger Wert für die Ressource, die an das Formular übergeben wird - wie beispielsweise die in der Datenbank gespeicherte ID.

In Ihrem vereinfachten Fall, die Sie in Ihrem Feld macht dies tun könnten: wenn zum Beispiel Ihrer onSubmit Aktion eines vorgelegten

<div key={this.props.value}> 
    <input type="text" defaultValue={this.props.value || ''} /> 
</div> 

In einem komplexeren Form Fall, so etwas wie dies könnte bekommen, was Sie wollen API blieb aber auf der gleichen Seite:

const Form = ({item, onSubmit}) => { 
    return (
    <form onSubmit={onSubmit} key={item.id}> 
     <label> 
     First Name 
     <input type="text" name="firstName" defaultValue={item.firstName} /> 
     </label> 
     <label> 
     Last Name 
     <input type="text" name="lastName" defaultValue={item.lastName} /> 
     </label> 
     <button>Submit!</button> 
    </form> 
) 
} 

Form.defaultProps = { 
    item: {} 
} 

Form.propTypes = { 
    item: PropTypes.object, 
    onSubmit: PropTypes.func.isRequired 
} 

wenn unkontrollierte Formulareingaben verwenden, wir in der Regel kümmern sich nicht um die Werte erst, nachdem sie eingereicht werden, ist also, warum es ideal ist, um nur eine Kraft wiederzugeben, wenn Sie möchten die defaultValues ​​wirklich aktualisieren (nach dem Senden, nicht bei jeder Änderung der einzelnen Eingabe).

Wenn Sie auch die gleiche Form bearbeiten und befürchten, dass die API-Antwort mit anderen Werten zurückkommen könnte, könnten Sie einen kombinierten Schlüssel wie id plus timestamp bereitstellen.

+2

sollte dies die beste Antwort sein –

Verwandte Themen