mobx 对删除行的反应应该触发两次以更新视图
mobx react for deleting row should trigger twice to update view
我在 react
中遇到 mobx
的问题。
我用 antd
组件制作了一个 table。我想在单击行时删除该行
因此,当我单击时,我触发了一个使用 delete 方法的 @action,然后触发了 get 请求的 @action。当我单击删除图标时,它会在我的服务器中删除我用 nodeJs 创建的,但它不会重新呈现 table,当我再次单击删除时,它会重新呈现。但在网络选项卡中,两个请求都是相同的。
感谢任何帮助。
我的 nodeJs 删除方法:
app.delete("/api/accommodation/delete/:id", function(req, res) {
fs.readFile("./data/accommodation.json", function(err, data) {
var deleteId = req.params.id;
console.log("deleted", deleteId);
const parsedData = JSON.parse(data);
parsedData.map((item, index) => {
if (item.id == deleteId) {
parsedData.splice(index, 1);
}
});
fs.writeFile(
"./data/accommodation.json",
JSON.stringify(parsedData),
function(error, writeData) {}
);
});
res.end();
});
我的table:
import React, { Component } from "react";
const ReactDOM = require("react-dom");
import { Layout, Table, Row, Col, Button, Input, Pagination } from "antd";
import { inject, observer } from "mobx-react";
import { observable } from "mobx";
import { MdSearch } from "react-icons/md";
const { Header, Content } = Layout;
const Search = Input.Search;
@inject("stores")
@observer
export default class Services extends Component {
@observable
store = this.props.stores.services;
componentDidMount() {
this.store.getAccommodationData(this.store.tableQuery);
}
render() {
return (
<div>
<Layout>
<Header>
<h3>خدمات</h3>
</Header>
<Content style={{ marginTop: "100px" }}>
<Row>
<Col span={20} offset={2}>
<Row>
<Col span={2}>
<Button type="primary">new +</Button>
</Col>
</Row>
<br />
<Row>
<Col span={5}>
<Input
placeholder="Enter your username"
prefix={<MdSearch />}
value={this.store.searchField}
onChange={e => this.store.onSearch(e)}
/>
</Col>
</Row>
<br />
<Row>
<Col span={24}>
<Table
dataSource={this.store.dataSource}
columns={this.store.columns}
pagination={false}
rowKey={record => record.id}
onChange={this.store.changeTable}
/>
<Row>
<br />
<Col span={24}>
<Pagination
style={{ direction: "ltr" }}
defaultCurrent={1}
total={this.store.totalPage}
pageSize={1}
onChange={e => this.store.pageChange(e)}
/>
</Col>
</Row>
</Col>
</Row>
</Col>
</Row>
</Content>
</Layout>
</div>
);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
我的店铺:
import { observable, action } from "mobx";
import React from "react";
import { MdEdit } from "react-icons/md";
export default class Services {
@observable
dataSource = [];
@observable
columns = [
{
title: "Id",
dataIndex: "id",
key: "id"
},
{
sorter: true,
title: "Name",
dataIndex: "name",
key: "name"
},
{
sorter: true,
title: "Provider",
dataIndex: "provider",
key: "provider"
},
{
sorter: true,
title: "Location",
dataIndex: "location",
key: "location"
},
{
title: "Type",
dataIndex: "type",
key: "type"
},
{
title: "Action",
key: "action",
render: (text, record) => (
<span>
<MdEdit
style={{ cursor: "pointer" }}
onClick={() => this.deleteRow(record)}
/>
</span>
)
}
];
@observable
totalPage = 0;
@observable
currentPage = 1;
@observable
tableQuery = {
c: 5,
p: this.currentPage,
s: "",
sk: "",
d: "",
q: ""
};
@observable
sortKey = "";
@observable
sortOrder = "";
@observable
searchField = "";
@action
deleteRow(record) {
console.log("deleted");
this.deleteData(record.id);
}
@action
async deleteData(id) {
fetch("http://localhost:1234/api/accommodation/delete/" + id, {
method: "DELETE"
})
.then(this.getAccommodationData(this.tableQuery))
.then(console.log(this.dataSource));
}
@action
changeTable = (pagination, filters, sorter) => {
this.sortKey = sorter.field;
this.sortOrder = sorter.order;
this.tableQuery.sk = this.sortKey;
if (this.sortOrder == "ascend") {
this.tableQuery.s = "asc";
} else if (this.sortOrder == "descend") {
this.tableQuery.s = "dec";
}
this.getAccommodationData(this.tableQuery);
};
@action
pageChange(pageNumber) {
this.currentPage = pageNumber;
this.tableQuery.p = this.currentPage;
this.getAccommodationData(this.tableQuery);
}
@action
onSearch(e) {
this.searchField = e.target.value;
if (this.searchField != "") {
this.tableQuery.d = 1;
}
this.tableQuery.q = this.searchField;
this.getAccommodationData(this.tableQuery);
}
@action
async getAccommodationData(query = this.tableQuery) {
fetch(
"http://localhost:1234/api/accommodation?" +
"c=" +
query.c +
"&p=" +
query.p +
"&s=" +
query.s +
"&sk=" +
query.sk +
"&d=" +
query.d +
"&q=" +
query.q,
{
method: "GET",
cors: "no-cors"
}
)
.then(response => response.json())
.then(data => {
this.dataSource = data.requestedData;
this.totalPage = data.total;
});
}
}
我自己发现了问题。
当我在我的删除函数中调用 get 函数时,我承诺我没有 return
我应该这样做 :
.then(() => this.getAccommodationData(this.tableQuery))
而不是这个:
.then(this.getAccommodationData(this.tableQuery))
我在 react
中遇到 mobx
的问题。
我用 antd
组件制作了一个 table。我想在单击行时删除该行
因此,当我单击时,我触发了一个使用 delete 方法的 @action,然后触发了 get 请求的 @action。当我单击删除图标时,它会在我的服务器中删除我用 nodeJs 创建的,但它不会重新呈现 table,当我再次单击删除时,它会重新呈现。但在网络选项卡中,两个请求都是相同的。
感谢任何帮助。
我的 nodeJs 删除方法:
app.delete("/api/accommodation/delete/:id", function(req, res) {
fs.readFile("./data/accommodation.json", function(err, data) {
var deleteId = req.params.id;
console.log("deleted", deleteId);
const parsedData = JSON.parse(data);
parsedData.map((item, index) => {
if (item.id == deleteId) {
parsedData.splice(index, 1);
}
});
fs.writeFile(
"./data/accommodation.json",
JSON.stringify(parsedData),
function(error, writeData) {}
);
});
res.end();
});
我的table:
import React, { Component } from "react";
const ReactDOM = require("react-dom");
import { Layout, Table, Row, Col, Button, Input, Pagination } from "antd";
import { inject, observer } from "mobx-react";
import { observable } from "mobx";
import { MdSearch } from "react-icons/md";
const { Header, Content } = Layout;
const Search = Input.Search;
@inject("stores")
@observer
export default class Services extends Component {
@observable
store = this.props.stores.services;
componentDidMount() {
this.store.getAccommodationData(this.store.tableQuery);
}
render() {
return (
<div>
<Layout>
<Header>
<h3>خدمات</h3>
</Header>
<Content style={{ marginTop: "100px" }}>
<Row>
<Col span={20} offset={2}>
<Row>
<Col span={2}>
<Button type="primary">new +</Button>
</Col>
</Row>
<br />
<Row>
<Col span={5}>
<Input
placeholder="Enter your username"
prefix={<MdSearch />}
value={this.store.searchField}
onChange={e => this.store.onSearch(e)}
/>
</Col>
</Row>
<br />
<Row>
<Col span={24}>
<Table
dataSource={this.store.dataSource}
columns={this.store.columns}
pagination={false}
rowKey={record => record.id}
onChange={this.store.changeTable}
/>
<Row>
<br />
<Col span={24}>
<Pagination
style={{ direction: "ltr" }}
defaultCurrent={1}
total={this.store.totalPage}
pageSize={1}
onChange={e => this.store.pageChange(e)}
/>
</Col>
</Row>
</Col>
</Row>
</Col>
</Row>
</Content>
</Layout>
</div>
);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
我的店铺:
import { observable, action } from "mobx";
import React from "react";
import { MdEdit } from "react-icons/md";
export default class Services {
@observable
dataSource = [];
@observable
columns = [
{
title: "Id",
dataIndex: "id",
key: "id"
},
{
sorter: true,
title: "Name",
dataIndex: "name",
key: "name"
},
{
sorter: true,
title: "Provider",
dataIndex: "provider",
key: "provider"
},
{
sorter: true,
title: "Location",
dataIndex: "location",
key: "location"
},
{
title: "Type",
dataIndex: "type",
key: "type"
},
{
title: "Action",
key: "action",
render: (text, record) => (
<span>
<MdEdit
style={{ cursor: "pointer" }}
onClick={() => this.deleteRow(record)}
/>
</span>
)
}
];
@observable
totalPage = 0;
@observable
currentPage = 1;
@observable
tableQuery = {
c: 5,
p: this.currentPage,
s: "",
sk: "",
d: "",
q: ""
};
@observable
sortKey = "";
@observable
sortOrder = "";
@observable
searchField = "";
@action
deleteRow(record) {
console.log("deleted");
this.deleteData(record.id);
}
@action
async deleteData(id) {
fetch("http://localhost:1234/api/accommodation/delete/" + id, {
method: "DELETE"
})
.then(this.getAccommodationData(this.tableQuery))
.then(console.log(this.dataSource));
}
@action
changeTable = (pagination, filters, sorter) => {
this.sortKey = sorter.field;
this.sortOrder = sorter.order;
this.tableQuery.sk = this.sortKey;
if (this.sortOrder == "ascend") {
this.tableQuery.s = "asc";
} else if (this.sortOrder == "descend") {
this.tableQuery.s = "dec";
}
this.getAccommodationData(this.tableQuery);
};
@action
pageChange(pageNumber) {
this.currentPage = pageNumber;
this.tableQuery.p = this.currentPage;
this.getAccommodationData(this.tableQuery);
}
@action
onSearch(e) {
this.searchField = e.target.value;
if (this.searchField != "") {
this.tableQuery.d = 1;
}
this.tableQuery.q = this.searchField;
this.getAccommodationData(this.tableQuery);
}
@action
async getAccommodationData(query = this.tableQuery) {
fetch(
"http://localhost:1234/api/accommodation?" +
"c=" +
query.c +
"&p=" +
query.p +
"&s=" +
query.s +
"&sk=" +
query.sk +
"&d=" +
query.d +
"&q=" +
query.q,
{
method: "GET",
cors: "no-cors"
}
)
.then(response => response.json())
.then(data => {
this.dataSource = data.requestedData;
this.totalPage = data.total;
});
}
}
我自己发现了问题。 当我在我的删除函数中调用 get 函数时,我承诺我没有 return 我应该这样做 :
.then(() => this.getAccommodationData(this.tableQuery))
而不是这个:
.then(this.getAccommodationData(this.tableQuery))