ReactJS 组件不渲染带有状态变量的 textarea

IT技术 javascript textarea reactjs
2021-05-23 10:22:14

我在 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>
               );
    }
}

您可能会注意到,它是在注册到我的 AppDispatcher 的商店中侦听控制器视图

正确执行上述步骤。即,当特定的动作triggerd,我的组件被正确使用变量渲染 {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 中正确打印字符串。

请注意,我的浏览器显示:

警告:使用defaultValuevalueprops而不是将孩子设置在 上<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以确保梯子不是空的。
  • 我把总结变成了defaultValueprops

这是输出: 在此处输入图片说明

第二次编辑:

我上传了一个突出问题的示例应用程序我希望这将有助于找到合适的解决方案

3个回答

从 react docs 检查此链接:React Textarea Value

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

正确的方法是

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

或者

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

value的区别defaultValue在于指定defaultValue会使组件不受控制

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

...同时指定value指示 React 控制组件,这意味着您需要更新 value 属性以确保更改反映在组件中:

由于 value 属性是在我们的表单元素上设置的,因此显示的值将始终是 this.state.value,从而使 React 状态成为真相的来源。

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

实际上,这正是错误的地方。文档

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

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

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

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

我使用了提升循环方法,效果很好。

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

希望这可以帮助。