我有三个React组件:第一个是容器(NoteContainer
组件),它负责在UI中呈现我的对象(Note
组件)。数据通过AJAX GET作为JSON获得。最后一个组件是窗体(NoteForm
),该窗体创建新对象(通过AJAX POST)。
POST的响应仅是新创建对象的JSON表示,而不是所有对象的JSON。NoteForm
应该将创建新对象后的JSON响应发送到NoteContainer
,将其附加到其state.data并重新呈现,或者NoteContainer
请求对象的完整列表并更新其状态日期完全?
我认为第一种方法更好,因为它不需要请求在NoteContainer状态下已经存在的数据。但是,我仍然不确定处理此问题的“最佳”方法。我应该给NoteContainer
另一个函数,例如addNewNote
,该函数将从NoteForm中获取JSON数据并将其附加到state.data吗?
我是React的新手,如果这个问题不清楚,我深表歉意。这是我的组件:
var NoteContainer = React.createClass({
getInitialState: function(){
return {data: []};
},
componentDidMount: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: function(data){
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err){
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
render: function(){
var noteNodes = this.state.data.map(function(note){
return (
<Note title={note.title} body={note.body} />
);
});
return (<div className='noteContainer'>{noteNodes}</div>);
}
});
var Note = React.createClass({
render: function(){
return (
<div className="note" >
<h1>{this.props.title}</h1>
<p>{this.props.body}</p>
</div>
);
}
});
var NoteForm = React.createClass({
getInitialState: function(){
return {'title': '', 'body': ''}
},
handleTitleChange: function(e){
this.setState({title: e.target.value});
},
handleBodyChange: function(e){
this.setState({body: e.target.value});
},
handleSubmit: function(e){
e.preventDefault();
var note = {
title: this.state.title,
body: this.state.body};
$.ajax({
url: this.props.url,
dataType: 'json',
type: 'POST',
data: note,
success: function(data){
// Send data to NoteContainer?
}.bind(this),
error: function(xhr, status, err){
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
render: function(){
return (
<form>
<input
type='text'
placeholder='Title'
value={this.state.title}
onChange={this.handleTitleChange} />
<textarea onChange={this.handleBodyChange}>
{this.state.body}
</textarea>
</form>
);
}
});
最佳答案
@xCrZx的建议是您将状态拉到各个组件之外,并拥有一个或多个顶级存储来维护状态。最简单的示例(即“香草”)是您的NoteContainer
是NoteForm
的父级。然后,您可以简单地将回调从NoteContainer
传递到NoteForm
:
var NoteContainer = React.createClass({
createNote: function() {
...
},
render: function() {
return (
...
<NoteForm createNote={this.createNote}>
...
);
}
});
var NoteForm = React.createClass({
props: {
createNote: React.PropTypes.func.isRequired
},
render: function() {
return (
...
onClick={this.props.createNote}
...
);
}
});
但是,只有在实际存在该关系的情况下,该方法才有效。现在,让我们看一下Reflux,在其中创建中心存储(以及与之相关的操作)以保存数据,并使组件“监听”存储。
var NoteActions = Reflux.createActins([
'createNote',
'getNotes'
]);
var NoteStore = Reflux.createStore({
listenables: [NoteActions],
init: {
// Notes is an empty array by default
this.notes = [];
},
getInitialState: function() {
return {
notes: this.notes
};
},
onCreateNote: function(noteFormData) { ...POST here, save note JSON to this.notes on success... },
onGetNotes: function() { ..GET here for the initial load...}
});
var NoteForm = React.createClass({
render: function() {
...
onClick={NoteActions.createNote(noteFormData)}
...
}
});
var NoteContainer = React.createClass({
mixins: [Reflux.connect(NoteStore)],
componentDidMount: function() {
NoteActions.getNotes();
},
render: function() {
return: function() {
.. same that you have now using this.state.notes
}
}
});
希望这开始有意义。强烈建议您仔细阅读Reflux(或Redux,相似但不同)的示例。