2015-06-09 13 views
8

Sono di fronte a un bug intrigante in React.Componente ReactJS che non restituisce textarea con la variabile di stato

ho questo componente:

'use strict'; 
import SummaryStore from '../stores/SummaryStore'; 
import React from 'react'; 

export default class ChangeSummaryForm extends React.Component { 
    constructor() { 
     // store initialisation 
     SummaryStore.register(); 

     var vRating = SummaryStore.getBookForSummaryPrint().summaryRating; 
     var vStarClassName = this.getRatingClasses(vRating); 
     this.state = { 
      sStarClassName: vStarClassName, 
      sCurrentBookToShow: SummaryStore.getBookForSummaryPrint() 
     }; 

     this.thereIsASummaryToShow = this.thereIsASummaryToShow.bind(this); 
    } 

    getRatingClasses(pRating) { 
     var vI, vStarClassName = []; 
     for(vI = 0; vI < 4; vI++) { 
      if(pRating > 0) { 
      vStarClassName.push("glyphicon glyphicon-star"); 
      pRating--; 
      } else { 
      vStarClassName.push("glyphicon glyphicon-star-empty"); 
      } 
     } 
     return vStarClassName; 
    } 
    componentDidMount() { 
    SummaryStore.addChangeListener(this.thereIsASummaryToShow); 
    } 

    componentWillUnmount() { 
    SummaryStore.removeChangeListener(this.thereIsASummaryToShow); 
    } 

    thereIsASummaryToShow() { 

     this.setState({sCurrentBookToShow: SummaryStore.getBookForSummaryPrint(), 
        sStarClassName: this.getRatingClasses(SummaryStore.getBookForSummaryPrint().rating) 
        }); 
     $("#summaryModal").modal('show'); 
    } 
    render() { 
     return (<div className="modal fade" id="summaryModal"> 
        <form> 
        <div className="modal-dialog"> 
        <div className="modal-content"> 
         <div className="modal-header"> 
         <button type="button" className="close" data-dismiss="modal" ariaLabel="Close"><span ariaHidden="true">&times;     </span>       </button> 
       <div style={{color: 'black'}}> 
        {this.state.sStarClassName.map(function(pCurrentClassName) { return (<span className={pCurrentClassName}></span> 
                        ); 
                       })} 
         <h4 className="modal-title">Summary of {this.state.sCurrentBookToShow.title}</h4> 
       </div> 
         </div> 
         <div className="modal-body"> 

          <div className="form-group"> 
           <textarea className="form-control" rows="22" ref="summaryContent" >{this.state.sCurrentBookToShow.summary}</textarea> 
          </div> 

         </div> 
         <div className="modal-footer"> 
         <button type="button" className="btn btn-default" data-dismiss="modal" >Close</button> 
         <input type="submit" className="btn btn-primary" value="Save"/> 
         </div> 
        </div> 
        </div> 
        </form> 
       </div> 
       ); 
    } 
} 

Come si può notare, si tratta di un controller-view l'ascolto in un negozio che è registrato al mio AppDispatcher.

I passaggi sopra riportati sono eseguiti correttamente. Ad esempio, quando la particolare azione è triggerd, il mio componente viene reso correttamente con le variabili {this.state.sCurrentBookToShow.title} e this.state.sCurrentBookToShow.title aggiornate.

Il problema viene da questa parte:

<textarea className="form-control" rows="22" ref="summaryContent" > 
    {this.state.sCurrentBookToShow.summary} 
</textarea> 

La stringa non viene stampata nella textarea.

ho provato questo per eseguire il debug:

render() { 
    var summary = "this is a summary"; 
    return (// .. shortened for brevity 
     <textarea className="form-control" rows="22" ref="summaryContent"> 
     {summary} 
    </textarea> ..); 
    } 

la stringa summary stampata correttamente all'interno del textearea mutevole.

Nota che il mio browser dice:

Attenzione: Usare i defaultValue o value oggetti di scena, invece di impostare bambini su <textarea>.

Ma lo aggiusterò più tardi poiché penso che non abbia un effetto sul problema corrente.

EDIT: Ho preso le sue osservazioni (finora) in considerazione, così ho aggiornato il mio codice in questo modo:

   <h4 className="modal-title">Summary of {this.state.sCurrentBookToShow.summary}</h4> 
     </div> 
       </div> 
       <div className="modal-body"> 

        <div className="form-group"> 
         {this.state.sCurrentBookToShow.summary} 
         <textarea className="form-control" rows="22" ref="summaryContent" defaultValue={this.state.sCurrentBookToShow.summary}></textarea> 
        </div> 
  • ho sostituito this.state.sCurrentBookToShow.title da .summary per rendere che la scala non è vuoto.
  • ho messo il riassunto in un defaultValue puntello

Ecco l'output: enter image description here

Seconda modifica:

ho caricato un campione app che mette in evidenza il problema. Spero che questo possa aiutare a trovare una soluzione adeguata

+1

Si prega di fornire un jsfiddle possiamo dare un'occhiata a. – gcedo

+0

@Edo My Appologies, ho difficoltà a caricarlo a causa delle dipendenze dell'architettura Flux ... Non so come impostare rapidamente un jsfiddle in questa situazione. – Mayas

+1

Puoi fare clic con il pulsante destro del mouse, ispezionare l'elemento all'interno dell'area di testo e segnalare cosa c'è dentro? – gcedo

risposta

14

controllare questo link da reagire docs: React Textarea Value

Fondamentalmente per textArea reagiscono non supporta testo racchiuso all'interno e piuttosto bisogno di specificare che come valore o defaultValue.

Il modo giusto è quindi

<textarea name="description" value="This is a description." /> 

o

<textarea name="description" defaultValue="This is a description." /> 

La differenza con il valore e defaultValue è che defaultValue si può sempre cambiare e il cambiamento sarà riflessa dal componente che è componente incontrollata . Ma se si utilizza il valore diventa un componente controllato ed è necessario aggiornare la proprietà valore per assicurarsi che la modifica si rifletta nel componente. Per avere un'idea chiara della differenza tra valore/valore predefinito, verificare questo: Fiddle for value Default Value Distinction La console mostrerà sempre un nuovo valore ma il componente no.

+1

Hai ragione. Ho usato valore e lo aggiorno su Change. Sembra l'unico modo. – Mayas

0

In realtà questo è esattamente ciò che è sbagliato. Da docs:

Se si desidera inizializzare il componente con un valore non vuoto, è possibile fornire un puntello Valore predefinito.

-2

Ho avuto lo stesso problema. L'ho risolto utilizzando componenti controllati, ad es.

state.value = this.props.value 
<textarea value={this.state.value} onchange={handler} /> 

Funziona bene per controllare la parte di ingresso. Tuttavia, ho avuto un altro problema, ho bisogno di inizializzare/cambiare il valore dello stato.valore di props.value ogni volta che c'è un ri-rendering.

Ho usato i metodi del ciclo di sollevamento e funziona perfettamente bene.

componentWillReceiveProps: function(){ 
    this.setState({ 
     value: this.props.value 
    }) } 

spero che questo aiuti.

+1

Non eseguire mai 'state.value = this.props.value'. Cambiare lo stato dovrebbe essere fatto con 'this.setState (...)', come hai fatto nel tuo componenteWillReceiveProps. – EatYaFood

Problemi correlati