React - 如何在 AJAX 请求后更新状态
React - How to Update State After AJAX Request
我一直在修补将 Web 应用程序中的一个页面转换为使用 react 而不是 jQuery 和 Vanilla JS,但由于我对 react 的不熟悉,我陷入了如何处理它的困境。
目前,在页面上,我有一个html表,其中包含与数据库表相关的行,另一列包含用于编辑和删除行的链接。
这是通过打开引导模式来完成的,其中包含一个表单,该表单是为编辑操作的相应行填充的,还有一个删除模式以确认删除,页面上还有一个链接可以添加新行,也是通过 AJAX,所以我试图做的是在 react 中复制它,但我似乎不明白如何去做。
目前我有这个(我在这个例子中使用了一个通用组件名称(ModelName
),以避免与它的实际名称混淆。
var ModelNames = React.createClass({
getInitialState: function() {
return {model_names: this.props.model_names};
},
render: function() {
var rows = [];
this.props.model_names.forEach(function(model_name) {
rows.push(<ModelName model_name={model_name} key={model_name.id} />);
});
return (
<div className="row">
<div className="col-md-12">
<table className="table table-striped table-bordered table-hover">
<thead>
<tr role="row" className="heading">
<th>Property 1</th>
<th>Property 2</th>
<th className="text-center">Options</th>
</tr>
</thead>
<tbody>{rows}</tbody>
</table>
</div>
</div>
);
}
});
var ModelName = React.createClass({
handleRemoveModelName: function() {
$.ajax({
url: '/model_name/ajax_delete',
data: { model_name_id: this.props.model_name.id },
type: 'POST',
cache: false,
success: function(data) {
this.setState({ model_names: data }); // this is the part I am having trouble with
}.bind(this),
error: function() {
console.log('error');
}.bind(this)
});
},
render: function() {
return (
<tr id={"model_name_" + this.props.model_name.id}>
<td>{this.props.model_name.property_1}</td>
<td>{this.props.model_name.property_2}</td>
<td className="text-center">
<a href="javascript:;" className="btn btn-xs" onClick={this.handleEditModelName}><i className="fa fa-pencil"></i></a> <a href="javascript:;" className="btn btn-xs" onClick={this.handleRemoveModelName}><i className="fa fa-remove"></i></a>
</td>
</tr>
);
}
});
ReactDOM.render(
// this comes from Rails
<ModelName model_names={<%= @model_names.to_json %>} />,
document.getElementById('react')
);
通过 ajax 删除工作正常,服务器端响应数据库表中的所有行(删除发生后),因此 json 响应的格式与页面加载时提供的初始数据完全相同,我只是想弄清楚如何更新状态,以便 react 知道删除我刚刚删除的记录。
同样,我想扩展它以复制我的编辑和创建 CRUD 功能,但在阅读了许多博客文章后,我正在努力找到我需要的信息。
更新
var ModelNames = React.createClass({
handleRemoveModelName: function(id) {
$.ajax({
url: '/model_name/ajax_delete',
data: { model_name_id: id },
type: 'POST',
cache: false,
success: function(data) {
this.setState({ model_names: data });
}.bind(this),
error: function() {
console.log('error');
}.bind(this)
});
},
render: function() {
var rows = [];
this.props.model_names.map(function(model_name) {
return (
<ModelName
model_name={model_name}
key={model_name.id}
onRemove={this.handleRemoveModelName}
/>
);
}, this);
// ...
}
});
var ModelName = React.createClass({
handleRemoveModelName: function() {
this.props.onRemove(this.props.model_name.id);
},
// ...
});
此外,只是为了尝试包含所有相关内容,删除按钮仍然具有onClick={this.handleRemoveModelName}
用于ModelName
return
。
除了 Felix Kling 的回答之外,您还需要以某种方式在ModalNames
和ModalName
之间进行通信以更新状态,因为状态由 ModalNames
管理,并且事件在 ModalName
中调用。
一种解决方案是将更新状态的函数传递给ModalName
:
模态名称:
var ModelNames = React.createClass({
...
updateState: function(modal_names) {
this.setState({modal_names})
},
render: function() {
var rows = [];
this.state.model_names.forEach(function(model_name) {
rows.push(<ModelName model_name={model_name} key={model_name.id} updateState={this.updateState} />);
});
...
}
}
模态名称:
var ModelName = React.createClass({
handleRemoveModelName: function() {
$.ajax({
url: '/model_name/ajax_delete',
data: { model_name_id: this.props.model_name.id },
type: 'POST',
cache: false,
success: function(data) {
this.props.updateState(data);
}.bind(this),
error: function() {
console.log('error');
}.bind(this)
});
},
...
}
另一种解决方案是在ModalNames
中定义handleRemoveModelName
,它接受id,调用ajax,并像你最初一样设置状态。
您必须确定数据的真实来源应该在哪里。在您当前的设置中,它似乎处于ModelNames
中。
与其让ModelName
执行删除,不如让ModelNames
执行删除,因为它拥有数据。
只需将请求删除时调用的回调传递给ModelName
即可。在此示例中,我们将向子组件添加一个新属性,单击删除按钮时调用该属性onRemove
:
var ModelNames = React.createClass({
handleRemoveModelName: function(id) {
// make Ajax call here
},
render: function() {
var rows = this.state.model_names.map(function(model_name) {
return (
<ModelName
model_name={model_name}
key={model_name.id}
onRemove={this.handleRemoveModelName}
/>
);
}, this);
// ...
}
});
var ModelName = React.createClass({
handleRemoveModelName: function() {
this.props.onRemove(this.props.model_name.id);
},
// ...
});
然后,父组件可以决定它想要如何响应这一点并进行适当的 Ajax 调用。
这使得ModuleName
成为"转储"组件。它与数据管理没有任何关系,只呈现它传递的数据。
另一个问题是你从ModelNames
(this.props.model_names
)的道具中读取,而不是状态。状态和道具是不同的。您需要从状态(this.state.model_names
)读取,以便在状态更改时更新组件。
- 在Rails中更新Div,而不更改更新请求后的视图
- 如何在执行 Ajax 请求大量数据库更新时实现进度条
- 使用rails中的ajax请求更新DB
- 如何在alt.js中使用源成功请求后更新状态
- 所选列表元素不会保持选中状态(通过ajax请求更新后)
- RxJS异步请求更新
- 多久向服务器发送一次Http请求以检查更新?(Ajax)
- RxJS:在每次返回并行http请求时更新客户端
- 如何使用每个ajax请求更新实例变量
- Angular没有't在http请求后更新我的对象
- 轮询更新主干模型/视图的请求
- Angular 在 http 请求后不更新页面(范围问题?
- 在每个请求 nodejs 中获取更新的文件
- 如何注册要在更新面板请求完成时运行的函数
- AngularJS:在成功的HTTP请求后更新指令范围
- 单击“更新”按钮后,请求不以“放置”形式进行,而是以“POST”形式发送
- 使用 ajax 请求更新数据表
- Javascript POST请求更新,没有HTML文本更新
- 根据 Ajax 请求更新整个页面
- 速率限制AJAX请求更新内容以避免重复