ReactJS组件不使用状态变量呈现textarea

时间:2015-06-09 11:10:52

标签: javascript textarea reactjs

我在React面临一个有趣的错误。

我有这个组件:

'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上注册的商店进行监听。

正确执行上述步骤。即,当触发特定操作时,我的组件正确呈现,变量{this.state.sCurrentBookToShow.title}this.state.sCurrentBookToShow.title是最新的。

问题来自这一部分:

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

字符串不会打印在textarea中。

我试过这个调试:

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

summary字符串在可变textearea中正确打印。

请注意,我的浏览器说:

  

警告:使用defaultValuevalue道具代替设置   <textarea>上的孩子。

但是我会稍后解决这个问题,因为我认为它对目前的问题没有影响。

修改 我考虑了你的评论(到目前为止),所以我更新了我的代码:

                <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。我希望这有助于找到合适的解决方案

3 个答案:

答案 0 :(得分:34)

从反应文档中查看此链接:React Textarea Value

基本上textArea react不支持包含在其中的文本,您需要将其指定为 value defaultValue

正确的方法是

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

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

valuedefaultValue的区别在于specifying defaultValue leaves the component uncontrolled

  

对于不受控制的组件,您通常希望React指定初始值,但不会使后续更新失效。要处理这种情况,您可以指定defaultValue属性而不是value。

... while specifying value instructs React to control the component,意味着您需要更新value属性以确保更改反映在组件中:

  

由于在我们的表单元素上设置了value属性,显示的值将始终为this.state.value,使React状态成为事实的来源。

要清楚了解值/默认值之间的差异,请检查:Fiddle for value Default Value Distinction 控制台将始终显示新值但组件不会显示。

答案 1 :(得分:0)

实际上这正是错误的。来自docs

  

如果要使用非空值初始化组件,可以提供defaultValue prop。

答案 2 :(得分:-3)

我遇到了同样的问题。我通过使用受控组件来解决它,例如

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

它可以很好地控制输入部分。但是,我有另一个问题,我需要在重新渲染时初始化/将state.value更改为props.value。

我使用了升力循环方法,它完美无缺。

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

希望这会有所帮助。