2014-10-14 17 views
22

Sto provando a "ripristinare" un elemento ReactJS.Come "resettare" un elemento ReactJS?

In questo caso, l'elemento è del 90% + del contenuto della pagina.

Sto usando replaceState per sostituire lo stato dell'elemento con il suo stato iniziale.

Sfortunatamente, i sottoelementi che hanno il loro 'stato' non vengono ripristinati. In particolare, i campi modulo mantengono il loro contenuto.

C'è un modo per forzare un re-rendering di un elemento, che causerà anche il ri-rendering dei sottoelementi, come se la pagina fosse appena stata caricata?

+0

Si dovrebbe probabilmente passare lo stato come oggetti di scena ai bambini – David

+0

Se si utilizza il paradigma [componenti controllati] (https://facebook.github.io/react/docs/forms.html#controlled-components) menzionato nei documenti di React e memorizza lo stato in alto nella gerarchia in cui stai chiamando 'replaceState', puoi "resettare" anche lo stato del modulo. –

+1

@ssorallen Gli input sono incorporati in elementi che hanno le loro funzionalità e comunicazioni con il server. per esempio. un campo "username" che esegue il controllo AJAX per i duplicati, come parte della convalida * field *. – fadedbee

risposta

49

L'aggiunta di un elemento key all'elemento forza la restituzione dell'elemento (e di tutti i relativi elementi secondari) quando tale chiave cambia.

(ho impostato il valore di 'chiave' semplicemente il timestamp di quando i dati iniziali è stato inviato.)

render: function() { 
    return (
    <div key={this.state.timestamp} className="Commissioning"> 
     ... 
1

Mentre io personalmente non credo che si dovrebbe conservare locali, statali componente intermedia (come caselle di input in corso) in una posizione centralizzata (come un flux store) nella maggior parte dei casi, qui può avere senso, a seconda di quante ne hai, specialmente dal momento che sembra che gli input abbiano già qualche interazione/convalida del server attorno a loro. Spingere questo stato nella gerarchia dei componenti o in un'altra posizione centrale può essere di grande aiuto in questo caso.

Un'idea alternativa che mi viene in mente è quella di utilizzare un mixin in componenti che potrebbero aver bisogno di reimpostare lo stato locale, e fare qualche tipo di attivazione di eventi, ecc. Per farlo accadere. Ad esempio, è possibile utilizzare il nodo del EventEmitter o una libreria come EventEmitter3 con un mixin come questo (attenzione: non testato, forse meglio questo come pseudocodice :)

var myEmitter = new EventEmitter(); // or whatever 

var ResetStateMixin = { 
    componentWillMount: function() { 
    myEmitter.on("reset", this._resetState); 
    }, 

    componentWillUnmount: function() { 
    myEmitter.off("reset", this._resetState); 
    }, 

    _resetState: function() { 
    this.replaceState(this.getInitialState()); 
    }, 

    triggerReset: function() { 
    myEmitter.emit("reset"); 
    } 
}; 

allora si potrebbe utilizzare in componenti in questo modo:

React.createClass({ 
    mixins: [ResetStateMixin], 

    getInitialState: function() { 
    return { ... }; 
    }, 

    onResetEverything: function() { 
    // Call this to reset every "resettable" component 
    this.triggerReset(); 
    } 
}); 

Questo è molto semplice e piuttosto pesante mano (è possibile ripristinare solo tutti i componenti, tutti i componenti chiama replaceState(this.getInitialState()), ecc), ma questi problemi potrebbe essere risolto estendendo mixin un po '(per esempio avere più emettitori di eventi, permettendo componente specifiche implementazioni resetState e così via).

Vale la pena notare che l'utente do deve utilizzare gli input controllati affinché funzioni; anche se non è necessario spingere lo stato fino in cima alla gerarchia dei componenti, sarà comunque necessario che tutti i tuoi input abbiano i gestori value e onChange (ecc.).

+0

In quali circostanze è meglio aggiungere un "tasto" all'elemento? – fadedbee

+0

@brandon, posso chiederti di dare un'occhiata a una domanda relativa al 'Reazione di rendering' qui: http://stackoverflow.com/questions/27913004/react-js-render-a-component-from-outside-react? –

+0

Sono d'accordo con te sulla soluzione del flusso. Mi viene in mente solo la possibilità di lanciare un'azione ogni volta che la forma cambia (c'è un cambio di input). – backdesk

6

Il metodo this.replaceState(this.getInitialState()) in realtà non ripristina i bambini che sono ingressi, se questo è quello che stai cercando. Per coloro che desiderano semplicemente ripristinare i loro campi modulo, esiste una funzione DOM reset() standard che cancellerà tutti gli input in un determinato elemento.

Quindi, con Reagire, sarebbe qualcosa di simile:

this.refs.someForm.getDOMNode().reset(); 

Doumentation:

https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/reset

4

Se si tratta di una forma che si desidera ripristinare, si può semplicemente utilizzare questo

// assuming you've given {ref: 'form'} to your form element 
React.findDOMNode(this.refs.form).reset();