我在子组件中调用axios delete方法,并希望刷新父组件以作出反应。当delete()调用时,它从数据库中删除了该行,但需要手动重新加载。没有手动重新加载怎么办?
我想删除方法,并且ProductList.js也同时更新。
import React, { Component } from "react";
import axios from "axios";
import Table from "./Table";
class ProductList extends Component {
constructor(props) {
super(props);
this.state = { productData: [] };
}
componentDidMount() {
axios
.get("http://localhost:8080/products")
.then((response) => {
console.log("responseProductList==", response);
this.setState({ productData: response.data });
})
.catch(function (error) {
console.log(error);
});
}
tabRow() {
return this.state.productData.map(function (object, i) {
return <Table obj={object} key={i} />;
});
}
render() {
return (
<div style={{ paddingTop: "25px" }}>
<h4 align="center">Product List</h4>
<table className="table table-striped" style={{ marginTop: 10 }}>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Price</th>
<th colSpan="4">Action</th>
</tr>
</thead>
<tbody>{this.tabRow()}</tbody>
</table>
</div>
);
}
}
export default ProductList;
import React, { Component } from "react";
import axios from "axios";
import { Link, withRouter } from "react-router-dom";
// import ProductList from "./ProductList";
// import AddProduct from "./AddProduct";
class Table extends Component {
// constructor(props) {
// super(props);
// }
deleteProduct = () => {
console.log("delete button clicked");
axios
.delete("http://localhost:8080/products/" + this.props.obj.id)
.then((res) => {
if (res.status === 200) {
alert("getStatusInDelete");
// return axios.get("http://localhost:8080/products/");
// this.forceUpdate(<ProductList />);
this.props.history.push("/ProductList");
} else {
console.log("Not refresh");
}
})
.catch((err) => console.log(err));
};
render() {
return (
<tr>
<td>{this.props.obj.id}</td>
<td>{this.props.obj.name}</td>
<td>{this.props.obj.price}</td>
<td>
<Link
to={"/EditProduct/" + this.props.obj.id}
className="btn btn-success"
>
Edit
</Link>
</td>
<td>
<button
type="button"
onClick={this.deleteProduct}
className="btn btn-danger"
>
Delete
</button>
</td>
</tr>
);
}
}
export default withRouter(Table);
答案 0 :(得分:2)
成功删除产品后,您需要更新父状态。
方法是在父组件中定义更新逻辑,然后在删除成功后从子组件中调用该函数。
// Define your update product logic here
// It will get productId (or any other unique key) as parameter
// and will use that unique key to update the producsts
// I've added an example logic but yours can be different
updateProducts = (productId) => {
let productsClone = { ...this.state.productData };
const productIndex = productsClone.findIndex(item => item.id == productId);
if (productIndex > -1) {
productsClone.splice(productIndex, 1);
this.setState({ productData: productsClone });
}
}
tabRow() {
return this.state.productData.map(function (object, i) {
// pass your `this.updateProducts` as a props to your child component
return <Table obj={object} key={i} updateProducts={this.updateProducts} />;
});
}
deleteProduct = () => {
axios
.delete("http://localhost:8080/products/" + this.props.obj.id)
.then((res) => {
if (res.status === 200) {
// Finally, here, call the updateProucts when API return success and make sure to pass the correct key as a parameter
this.props.updateProducts(res.data.id);
} else {
console.log("Not refresh");
}
})
.catch((err) => console.log(err));
};
答案 1 :(得分:2)
首先,您不应使用索引作为键,而应使用产品的ID,因为如果使用索引,则删除后可能会遇到奇怪的错误。 要更新列表,我将传递一个回调onDelete(id)并在父级中处理它。 像这样:
import React, { Component } from "react";
import axios from "axios";
import Table from "./Table";
class ProductList extends Component {
constructor(props) {
super(props);
this.state = { productData: [] };
}
componentDidMount() {
axios
.get("http://localhost:8080/products")
.then((response) => {
console.log("responseProductList==", response);
this.setState({ productData: response.data });
})
.catch(function (error) {
console.log(error);
});
}
//****** This is the callback you are going to pass ********
onProductDeleted = (id) => {
this.setState((state) => ({ productData: state.productData.filter(x => x.id !== id) })
}
tabRow() {
return this.state.productData.map(object => {
//********* Passing the callback ************
return <Table obj={object} key={object.id} onDeleted={this.onProductDeleted} />;
});
}
render() {
return (
<div style={{ paddingTop: "25px" }}>
<h4 align="center">Product List</h4>
<table className="table table-striped" style={{ marginTop: 10 }}>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Price</th>
<th colSpan="4">Action</th>
</tr>
</thead>
<tbody>{this.tabRow()}</tbody>
</table>
</div>
);
}
}
export default ProductList;
import React, { Component } from "react";
import axios from "axios";
import { Link, withRouter } from "react-router-dom";
class Table extends Component {
deleteProduct = () => {
console.log("delete button clicked");
axios
.delete("http://localhost:8080/products/" + this.props.obj.id)
.then((res) => {
if (res.status === 200) {
alert("getStatusInDelete");
this.props.history.push("/ProductList");
//****** Invoke the callback after successfully deleted *****
this.props.onDeleted(this.props.obj.id);
} else {
console.log("Not refresh");
}
})
.catch((err) => console.log(err));
};
render() {
return (
<tr>
<td>{this.props.obj.id}</td>
<td>{this.props.obj.name}</td>
<td>{this.props.obj.price}</td>
<td>
<Link
to={"/EditProduct/" + this.props.obj.id}
className="btn btn-success"
>
Edit
</Link>
</td>
<td>
<button
type="button"
onClick={this.deleteProduct}
className="btn btn-danger"
>
Delete
</button>
</td>
</tr>
);
}
}
export default withRouter(Table);
以下是一些您可以参考的资料,可以增进您对React的理解:
答案 2 :(得分:0)
最终答案:经过稍微编辑,现在可以正常使用。
import React, { Component } from "react";
import axios from "axios";
import Table from "./Table";
class ProductList extends Component {
constructor(props) {
super(props);
this.state = { productData: [] };
}
componentDidMount() {
axios
.get("http://localhost:8080/products")
.then((response) => {
console.log("responseProductList==", response);
this.setState({ productData: response.data });
})
.catch(function (error) {
console.log(error);
});
}
//****** This is the callback you are going to pass ********
onProductDeleted = (id) => {
this.setState((state) => ({ productData: state.productData.filter(x => x.id !== id) })
)}
tabRow = () => {
return this.state.productData.map(object => {
//********* Passing the callback ************
return <Table obj={object} key={object.id} onDeleted={this.onProductDeleted} />;
});
}
render() {
return (
<div style={{ paddingTop: "25px" }}>
<h4 align="center">Product List</h4>
<table className="table table-striped" style={{ marginTop: 10 }}>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Price</th>
<th colSpan="4">Action</th>
</tr>
</thead>
<tbody>{this.tabRow()}</tbody>
</table>
</div>
);
}
}
export default ProductList;
import React, { Component } from "react";
import axios from "axios";
import { Link, withRouter } from "react-router-dom";
class Table extends Component {
deleteProduct = () => {
console.log("delete button clicked");
axios
.delete("http://localhost:8080/products/" + this.props.obj.id)
.then((res) => {
if (res.status === 200) {
alert("getStatusInDelete");
// this.props.history.push("/ProductList");
//****** Invoke the callback after successfully deleted *****
this.props.onDeleted(this.props.obj.id);
} else {
console.log("Not refresh");
}
})
.catch((err) => console.log(err));
};
render() {
return (
<tr>
<td>{this.props.obj.id}</td>
<td>{this.props.obj.name}</td>
<td>{this.props.obj.price}</td>
<td>
<Link
to={"/EditProduct/" + this.props.obj.id}
className="btn btn-success"
>
Edit
</Link>
</td>
<td>
<button
type="button"
onClick={this.deleteProduct}
className="btn btn-danger"
>
Delete
</button>
</td>
</tr>
);
}
}
export default withRouter(Table);