ReactJS 组件不使用状态变量渲染文本区域
ReactJS component not rendering textarea with state variable
我在 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">× </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>
该字符串未打印在文本区域中。
我试过这个来调试:
render() {
var summary = "this is a summary";
return (// .. shortened for brevity
<textarea className="form-control" rows="22" ref="summaryContent">
{summary}
</textarea> ..);
}
summary
字符串在可变文本区域中正确打印。
注意我的浏览器显示:
Warning: Use the defaultValue
or value
props instead of setting
children on <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>
- 我用
.summary
替换了 this.state.sCurrentBookToShow.title
来制作
确保梯子不是空的。
- 我把总结放到了
defaultValue
prop
这是输出:
第二次编辑:
我上传了一个样本 app 突出了这个问题。我希望这有助于找到合适的解决方案
实际上,这正是错误所在。来自 docs:
If you want to initialize the component with a non-empty value, you can supply a defaultValue prop.
从 React 文档中检查此 link:React Textarea Value
基本上,对于 textArea,React 不支持包含在其中的文本,您需要将其指定为 value
或 defaultValue
.
正确的方法是
<textarea name="description" value="This is a description." />
或
<textarea name="description" defaultValue="This is a description." />
与value
和defaultValue
的区别在于specifying defaultValue
leaves the component uncontrolled:
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.
...而 specifying value
instructs React to control the component,这意味着您需要更新值 属性 以确保更改反映在组件中:
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.
要清楚地了解值/默认值之间的差异,请检查以下内容:Fiddle for value Default Value Distinction 控制台将始终显示新值,但组件不会。
我遇到了同样的问题。我通过使用受控组件解决了它,例如
state.value = this.props.value
<textarea value={this.state.value} onchange={handler} />
控制输入部分效果很好。但是,我还有另一个问题,只要有重新渲染,我就需要 init/change 将 state.value 更改为 props.value。
我使用了提升循环方法,效果非常好。
componentWillReceiveProps: function(){
this.setState({
value: this.props.value
}) }
希望这对您有所帮助。
我在 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">× </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>
该字符串未打印在文本区域中。
我试过这个来调试:
render() {
var summary = "this is a summary";
return (// .. shortened for brevity
<textarea className="form-control" rows="22" ref="summaryContent">
{summary}
</textarea> ..);
}
summary
字符串在可变文本区域中正确打印。
注意我的浏览器显示:
Warning: Use the
defaultValue
orvalue
props instead of setting children on<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>
- 我用
.summary
替换了this.state.sCurrentBookToShow.title
来制作 确保梯子不是空的。 - 我把总结放到了
defaultValue
prop
这是输出:
第二次编辑:
我上传了一个样本 app 突出了这个问题。我希望这有助于找到合适的解决方案
实际上,这正是错误所在。来自 docs:
If you want to initialize the component with a non-empty value, you can supply a defaultValue prop.
从 React 文档中检查此 link:React Textarea Value
基本上,对于 textArea,React 不支持包含在其中的文本,您需要将其指定为 value
或 defaultValue
.
正确的方法是
<textarea name="description" value="This is a description." />
或
<textarea name="description" defaultValue="This is a description." />
与value
和defaultValue
的区别在于specifying defaultValue
leaves the component uncontrolled:
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.
...而 specifying value
instructs React to control the component,这意味着您需要更新值 属性 以确保更改反映在组件中:
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.
要清楚地了解值/默认值之间的差异,请检查以下内容:Fiddle for value Default Value Distinction 控制台将始终显示新值,但组件不会。
我遇到了同样的问题。我通过使用受控组件解决了它,例如
state.value = this.props.value
<textarea value={this.state.value} onchange={handler} />
控制输入部分效果很好。但是,我还有另一个问题,只要有重新渲染,我就需要 init/change 将 state.value 更改为 props.value。
我使用了提升循环方法,效果非常好。
componentWillReceiveProps: function(){
this.setState({
value: this.props.value
}) }
希望这对您有所帮助。