javascript ReactJS:如何从另一个组件更新组件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24884320/
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
ReactJS: How to update a component from another
提问by vitto
I'm trying to write a simple textarea
char counter widget with ReactJSto learn how to use it, but I'm now sure how I can set value by fire textarea onChange
event.
我正在尝试textarea
使用ReactJS编写一个简单的字符计数器小部件来学习如何使用它,但我现在确定如何通过触发textarea onChange
事件设置值。
This is how I've wrote the app:
这是我编写应用程序的方式:
/**
* @jsx React.DOM
*/
var EditorWidget = React.createClass({
render : function() {
return (
<div className="editor-widget">
<h4 className="title">Titolo articolo</h4>
<TextArea maxLength={this.props.maxLength}/>
<footer>
<TextStatus maxLength={this.props.maxLength} currentLength={this.props.currentLength}/>
<ActionButton />
</footer>
</div>
);
}
});
var TextArea = React.createClass({
onTextChanged : function(event) {
// how to update currentLength for TextStatus component?
this.props.currentLength = event.target.value.length;
},
render : function() {
return (
<textarea onChange={this.onTextChanged} maxLength={this.props.maxLength} placeholder="Lampadario con catino romagnolo"></textarea>
);
}
});
var TextStatus = React.createClass({
render : function() {
return (
<div className="info">
Caratteri<span className="small-left-margin">{this.props.currentLength} / {this.props.maxLength}</span>
</div>
);
}
});
var ActionButton = React.createClass({
render : function() {
return (
<div className="action remove">
Rimuovi elemento
</div>
);
}
});
React.renderComponent(
<EditorWidget maxLength="15" currentLength="0"/>,
document.getElementById("container")
);
From onTextChanged
method owned by TextArea
component I'm not sure on how I can change the state of TextStatus
component, how can I set the currentLength
of TextStatus
component?
从onTextChanged
所拥有的方法TextArea
成分我不知道我如何可以改变的状态TextStatus
组件,我怎么可以设置currentLength
的TextStatus
组成部分?
回答by Valéry
You cannot modify a prop with the public API, only a state. So we should start by moving currentLength into the state of EditorWidget. We add this method to EditorWidget:
您不能使用公共 API 修改 prop,只能修改state。所以我们应该首先将 currentLength 移动到 EditorWidget 的状态。我们将此方法添加到 EditorWidget:
getInitialState: function() {
return {currentLength: 0};
},
and pass the value by using this.state
instead of this.props
: <TextStatus currentLength={this.state.currentLength}
. Each time currentLength changes, TextStatus will be updated with the new value.
并通过使用this.state
而不是this.props
:传递值<TextStatus currentLength={this.state.currentLength}
。每次 currentLength 更改时,TextStatus 将使用新值更新。
Now we need the state to be updated each time the textarea emits a Change event. We can break this down into 2 steps: textarea emits a Change event to the TextStatus component, which reacts by emitting a custom event that carries the new length value. Let's call this custom event "TextChange".
现在我们需要在 textarea 每次发出 Change 事件时更新状态。我们可以将其分解为 2 个步骤: textarea 向 TextStatus 组件发出 Change 事件,该组件通过发出带有新长度值的自定义事件做出反应。我们将此自定义事件称为“TextChange”。
We proceed from the top down. In EditorWidget, we add a handler for TextChange, that reads the length and updates currentLength:
我们从上往下进行。在 EditorWidget 中,我们为 TextChange 添加一个处理程序,它读取长度并更新 currentLength:
handleTextChange: function(length) {
this.setState({currentLength: length});
},
and pass it around: <TextArea onTextChange={this.handleTextChange}
. in TextArea, we add a handler for Change that emits the new length via onTextChange:
并传递它:<TextArea onTextChange={this.handleTextChange}
。在 TextArea 中,我们为 Change 添加一个处理程序,通过 onTextChange 发出新的长度:
handleChange : function(event) {
var length = event.target.value.length;
this.props.onTextChange(length);
},
and pass it to the textarea: <textarea onChange={this.handleChange}
.
并将其传递给 textarea: <textarea onChange={this.handleChange}
。
We're done. Each time the user types in some text in the text area, the events bubble up the component hierarchy up to EditorWidget, which updates its state and triggers a re-render of its children, including TextStatus.
我们完成了。每次用户在文本区域中输入一些文本时,事件都会在组件层次结构中向上冒泡,直到 EditorWidget,它更新其状态并触发其子项的重新渲染,包括 TextStatus。
回答by z5h
You don't update a component from another.
您不会从另一个组件更新组件。
Instead: components render from a shared top level data model. Callbacks are passed down to components. Any one of them can trigger a data change on that data model through the callbacks. The model should trigger a re-render. All components now have the new value.
相反:组件从共享的顶级数据模型呈现。回调被传递给组件。它们中的任何一个都可以通过回调触发该数据模型上的数据更改。该模型应触发重新渲染。所有组件现在都具有新值。
My answer here provides an example of this: https://stackoverflow.com/a/24251931/131227
我在这里的回答提供了一个例子:https: //stackoverflow.com/a/24251931/131227
回答by mAydie
I don't think it's good practice, but you can do this:
我不认为这是一个好习惯,但你可以这样做:
Add a reference to your TextStatus component
添加对 TextStatus 组件的引用
<TextStatus ref="textStatus" ... />
Then in your TextArea component you can access it like this:
然后在您的 TextArea 组件中,您可以像这样访问它:
onTextChanged : function(event) {
this.props.currentLength = event.target.value.length;
// You need to add a textLength state to your TextStatus, then
this._owner.refs['textStatus'].setState({
currentLength: this.props.currentLength;
});
}
Your TextStatus become something like this:
你的 TextStatus 变成了这样:
var TextStatus = React.createClass({
getInitialState: function () {
return {
currentLength: 0
};
},
render : function() {
return (
<div className="info">
Caratteri<span className="small-left-margin">{this.state.currentLength} / {this.props.maxLength}</span>
</div>
);
}
});