2015-06-09 1 views
8

Я столкнулся с интригующей ошибкой в ​​реактиве.Компонент ReactJS не отображается textarea с переменной состояния

У меня есть этот компонент:

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

Как вы могли заметить, это controller-view прослушивания в магазине, который зарегистрирован на мой AppDispatcher.

Правильно выполненные шаги. то есть, когда конкретное действие является triggerd, мой компонент правильно отображается с переменными {this.state.sCurrentBookToShow.title} и this.state.sCurrentBookToShow.title.

Проблема исходит из этой части:

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

строка не печатается в текстовом поле.

Я попытался это отлаживать:

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

summary строка печатается правильно внутри изменяемого textearea.

Обратите внимание, что говорит мой браузер:

Предупреждение: Используйте defaultValue или value реквизита вместо установки детей на <textarea>.

Но я исправлю это позже, так как думаю, что это не влияет на текущую проблему.

EDIT: Я взял свои замечания (до сих пор) в рассмотрении, так что я обновил свой код так:

   <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> 
  • я заменил this.state.sCurrentBookToShow.title на .summary сделать уверен лестница не является пустой.
  • Я положил резюме в defaultValue реквизита

Вот результат: enter image description here

Второе редактирование:

Я загрузил образец app, который выдвигает на первый план проблему. Я надеюсь, что это поможет найти правильное решение.

+1

Пожалуйста, предоставьте jsfiddle, на который мы можем взглянуть. – gcedo

+0

@Edo Мои приложения, мне трудно загружать их из-за зависимостей архитектуры Flux ... Я не знаю, как быстро установить jsfiddle в этой ситуации. – Mayas

+1

Можете ли вы щелкнуть правой кнопкой мыши, проверить элемент внутри текстовой области и сообщить, что там? – gcedo

ответ

14

Проверить эту ссылку из реагировать Документы React Textarea Value

В основном для TEXTAREA реагировать не поддерживает текст, заключенный внутри и вам скорее нужно указать, что, как значения или DefaultValue.

Правильный путь, таким образом, является

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

или

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

Разница со значением и DefaultValue является то, что DefaultValue всегда можно изменить, и это изменение будет отражено компонентом является неконтролируемое компонентом , Но если вы используете значение, он становится управляемым компонентом, и вам нужно обновить свойство value, чтобы убедиться, что изменения отражены в компоненте. Чтобы получить четкое представление о различии между значением/значением по умолчанию, проверьте это: Fiddle for value Default Value Distinction Консоль всегда будет показывать новое значение, но компонент не будет.

+1

Вы правы. Я использовал значение и обновил его в элементе «Изменить». Это единственный способ. – Mayas

0

На самом деле это точно, что не так. От docs:

Если вы хотите инициализировать компонент непустым значением, вы можете предоставить опору по умолчанию.

-2

У меня была та же проблема. Я решил это, используя управляемый компонент, например.

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

Он отлично работает для управления входной частью. Тем не менее, у меня была другая проблема, мне нужно инициализировать/изменить state.value на props.value всякий раз, когда есть повторная рендеринг.

Я использовал методы подъемного цикла, и он отлично работает.

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

надеюсь, что это поможет.

+1

Никогда не делайте 'state.value = this.props.value'. Изменение состояния должно выполняться только с помощью 'this.setState (...)', как и в вашем компонентеWillReceiveProps. – EatYaFood

Смежные вопросы