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

Javascript ReactJS组件未使用状态变量呈现textarea,javascript,textarea,reactjs,Javascript,Textarea,Reactjs,我在React中遇到了一个有趣的bug 我有这个部分: 'use strict'; import SummaryStore from '../stores/SummaryStore'; import React from 'react'; export default class ChangeSummaryForm extends React.Component { constructor() { // store initialisation Summary

我在React中遇到了一个有趣的bug

我有这个部分:

'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>
               );
    }
}
文本区域中未打印字符串

我尝试了以下方法进行调试:

    render() {
     var summary = "this is a summary";
     return (// .. shortened for brevity
      <textarea className="form-control" rows="22" ref="summaryContent">
       {summary}
    </textarea> ..);
    }
  • 我用
    .summary
    替换了
    this.state.sCurrentBookToShow.title
    ,以使 确保梯子不是空的
  • 我将摘要放入
    defaultValue
    prop
以下是输出:

第二次编辑:


我上传了一个突出问题的示例。我希望这将有助于找到一个合适的解决方案实际上这正是问题所在。从:

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


从react docs中检查此链接:

基本上,对于textArea react,它不支持包含在中的文本,您需要将其指定为
默认值

因此,正确的方法是

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


value
defaultValue
的区别在于:

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

…同时,这意味着您需要更新value属性以确保更改反映在组件中:

'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>
               );
    }
}
由于在表单元素上设置了value属性,因此显示的值将始终是this.state.value,从而使React状态成为真理的来源


要清楚地了解值/默认值之间的差异,请检查以下内容:控制台将始终显示新值,但组件不会显示新值。

我也遇到了同样的问题。我用受控元件解决了这个问题,例如

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

希望这有帮助。

请提供一个JSFIDLE,我们可以看看。@Edo我的地址,由于Flux体系结构的依赖性,我很难上传它。。。在这种情况下,我不知道如何快速设置JSFIDLE。您可以右键单击,检查文本区域内的元素并报告其中的内容吗?请参考此快照:您可以注意到“defaultValue”道具似乎在渲染后被React忽略。您是对的。我使用了值,并在更改时更新它。这似乎是唯一的方法。本文链接到React的文档,对于理解受控组件和非受控组件之间的区别也很有用:Never do
state.value=This.props.value
。更改状态只需使用
this.setState(…)
,就像您在组件WillReceiveProps中所做的那样。
<textarea name="description" defaultValue="This is a description." />
state.value = this.props.value 
<textarea value={this.state.value} onchange={handler} />
componentWillReceiveProps: function(){
    this.setState({
        value: this.props.value
    }) }