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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30730369/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 05:40:22  来源:igfitidea点击:

ReactJS component not rendering textarea with state variable

javascripttextareareactjs

提问by Mayas

I am facing an intriguing bug in React.

我在 React 中遇到了一个有趣的错误。

I have this component:

我有这个组件:

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

As you might notice, it's a controller-viewlistening at a store which is registered to my AppDispatcher.

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

The steps above are correctly performed. i.e, when the particular action is triggerd, my component is correctly rendered with the variables {this.state.sCurrentBookToShow.title}and this.state.sCurrentBookToShow.titleup-to-date.

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

The problemcomes from this part:

问题来自这部分:

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

The string is not printed in the the textarea.

该字符串未打印在 textarea 中。

I tried this to debug:

我试过这个来调试:

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

the summarystring printed correctly inside the mutable textearea.

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

Note that my browser says:

请注意,我的浏览器说:

Warning: Use the defaultValueor valueprops instead of setting children on <textarea>.

警告:使用defaultValuevalue道具而不是将孩子设置在 上<textarea>

But I will fix this later since I think it doesn't have an effect on the current problem.

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

EDIT:I took your remarks (so far) in consideration, so I updated my code like so:

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

                <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>
  • I replaced this.state.sCurrentBookToShow.titleby .summaryto make sure the ladder is not empty.
  • I put the summary into a defaultValueprop
  • 我替换this.state.sCurrentBookToShow.title.summary以确保梯子不是空的。
  • 我将摘要放入defaultValue道具中

Here is the output: enter image description here

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

Second edit:

第二次编辑:

I uploaded a sample appthat highlights the issue. I hope this would help to find a proper solution

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

回答by Jyoti Puri

Check this link from react docs: React Textarea Value

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

Basically for textArea react does not supports text enclosed within and you rather need to specify that as valueor defaultValue.

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

The right way thus is

正确的方法是

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

or

或者

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

The difference with valueand defaultValueis that specifying defaultValueleaves the component uncontrolled:

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

With an uncontrolled component, you often want React to specify the initial value, but leave subsequent updates uncontrolled. To handle this case, you can specify a defaultValue attribute instead of value.

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

...while specifying valueinstructs React to control the component, meaning you need to update value property to make sure that change is reflected in the component:

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

Since the value attribute is set on our form element, the displayed value will always be this.state.value, making the React state the source of truth.

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

To get a clear idea of difference between value / default value check this: Fiddle for value Default Value Distinction Console will always show new value but component will not.

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

回答by gcedo

Actually that is exactly what is wrong. From the docs:

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

If you want to initialize the component with a non-empty value, you can supply a defaultValue prop.

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

回答by Jerry WU

I had the same problem. I solved it by using controlled component, e.g.

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

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

It works fine to control the input part. However, I had another issue, I need to init/change the state.value to props.value whenever there is a re-render.

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

I used the lift-cycle methods and it works perfect fine.

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

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

hope this helps.

希望这可以帮助。