[英]ReactJS: Maintain data state between parent and child
There's a parent, <MessageBox />
element, which contains a list of messages
stored in its state . 有一个
<MessageBox />
父元素,其中包含以state形式存储的messages
列表。 For each message
in messages
, a <Message />
element is created inside <MessageBox />
which has fields for message.subject
and message.body
. 对于每一个
message
中messages
,一个<Message />
被内部产生元件<MessageBox />
具有用于字段message.subject
和message.body
。 A user can edit the message.subject
and message.body
and once done, the message
object is sent back to <MessageBox />
through a props.updateHandler()
to maintain the message state in the parent. 用户可以编辑
message.subject
和message.body
,一旦完成,则通过props.updateHandler()
将message
对象发送回<MessageBox />
,以保持父对象中的消息状态。
In my current approach, I'm storing the message data in MessageBox
's state and in the render()
function, I'm creating the <Message />
elements and passing a callback to each of them to send back data changes. 在当前方法中,我将消息数据存储在
MessageBox
的状态中,并在render()
函数中,创建<Message />
元素,并将回调传递给每个元素以发送回数据更改。 In the callback, the updated data from each of the <Message />
elements is updated back into MessageBox
's state. 在回调中,来自每个
<Message />
元素的更新数据将更新回MessageBox
的状态。 The reason for this is to keep all the recent updated data in one place only. 这样做的原因是将所有最近更新的数据仅保留在一个位置。 The above approach creates havoc if
shouldComponentUpdate()
method in <Message />
is not overloaded (infinite recursion). 如果
<Message />
shouldComponentUpdate()
方法未过载(无限递归),则上述方法会造成严重破坏。
Is there a better approach for this? 有更好的方法吗? I've to write a lot of code just to override the builtin methods to keep the entire thing stable.
我必须编写大量代码以覆盖内置方法,以使整个过程保持稳定。 As I'm not planning to go for Flux/Redux, is there a React-only approach for this?
由于我不打算使用Flux / Redux,是否有只使用React的方法?
EDIT: Since there's a lot of confusion, I'm adding minimal code. 编辑:由于存在很多混乱,我添加了最少的代码。
class Message extends React.Component {
constructor(props) {
this.state = {
subject: this.props.subject,
body: this.props.body,
type: this.props.type,
messageIndex: this.props.messageIndex
};
}
componentDidUpdate() {
this.props.updateHandler(messageIndex, {
subject: this.state.subject,
body: this.state.body,
type: this.state.type
});
}
render() {
return (
<div>
<input
type="text"
defaultValue={this.state.subject}
onBlur={e => this.setState({subject: e.target.value})} />
<input
type="text"
defaultValue={this.state.subject}
onBlur={e => this.setState({body: e.target.value})} />
<select
type="text"
value={this.state.subject}
onChange={e => this.setState({type: e.target.value})}>
<option>Type 1</option>
<option>Type 2</option>
</select>
</div>
)
}
}
class MessageBox extends React.Component {
constructor(props) {
this.state = {
messages: aListOfMessageObjects
}
}
updateHandler(message) {
// Message update happens here and returns a list updatedMessages
this.setState({
messages: updatedMessages
});
}
render() {
let _this = this;
var messagesDOM = this.state.messages.map((m) => {
return (
<Message
message={m}
updateHandler={_this.updateHandler.bind(_this)} />
);
})
return (
<div>
{messagesDOM}
</div>
);
}
}
If that can help, read thinking-in-react . 如果有帮助,请阅读“行动中思考” 。 It explains how data should go only one way to avoid be lost in UI updates.
它解释了数据应该如何只不过是避免在UI更新中丢失的一种方式。
React ToDo MVC will provide you an example of React good practice on a real case React ToDo MVC将为您提供实际案例中的React最佳实践示例
To know how to pass props from your parent to children read controlled-components . 要知道如何将道具从父母那里传递给孩子,请阅读受控组件 。 you'll have to use
value
and onBlur
on each input. 您必须在每个输入上使用
value
和onBlur
。 Any onBlur
event will call this.props.updateHandler
with e
as parameter instead of e => this.setState({type: e.target.value})
. 任何
onBlur
事件都将使用e
作为参数而不是e => this.setState({type: e.target.value})
来调用this.props.updateHandler
。
MessageBox
from componentDidUpdate()
of Message
. Message
componentDidUpdate()
对MessageBox
进行回调。 Do a callback directly from an action in Message. Message
component at all. Message
组件中的状态。 Props will keep the values you are interested if you update parent's state properly. What you need is something like: 您需要的是这样的:
<input type="text"
defaultValue={this.props.subject}
onBlur={e => this.updateSubject(e.target.value)} />
updateSubject: function(newSubjectValue) {
this.props.updateHandler(messageIndex, {
subject: newSubjectValue,
body: this.props.body,
type: this.props.type
});
}
That way the component will get re-rendered, but won't do another call to the parent's setState. 这样,组件将被重新渲染,但不会再调用父对象的setState。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.