我有一个名为Cart
的父组件和另一个名为Items
的组件。
基本上,我是从Node.js获取对象数组并将其另存为Cart
组件中的状态。
我的购物车组件:
class Cart extends React.Component {
constructor(props){
super(props)
this.state={
cartData:null,
}
}
componentWillUnmount(){
_isMounted = false
}
componentDidMount() {
_isMounted = true
this.callApi()
.then(res => {if(_isMounted) this.setState({cartData: res.express})})
.catch(err => console.log(err));
}
callApi = async () => {
const response = await fetch('/myCart');
const body = await response.json();
if (response.status !== 200) throw Error(body.message);
return body;
};
mapOutItems(){
return this.state.cartData.map((item,index) => (
<Item
key={index}
desc={item.desc}
amount={item.amount}
total={item.total}
delete={this.handleDelete(item.desc)}
/>
))
}
handleDelete(desc){
axios({method: "post", url: "/remove", data:{name: desc}})
axios("/myCart").then(function (response){
this.setState({cartData : response.data.express})
})
.catch(function (error){
console.log(error)
});
}
render(){
return(
<div>
<div className="container">
{this.mapOutItems()}
</div>
</div>
)
}
}
export default Cart;
项目组件
class Item extends React.Component{
handleClick(e){
e.preventDefault()
axios({method: "post", url: "/remove", data:{name: this.props.desc}})
}
render(){
return(
<div>
<div className="row">
<div className="col">
{this.props.desc}
</div>
<div className="col">
{this.props.amount}
</div>
<div className="col">
{this.props.total}
</div>
<button className="btn btn-sm btn-danger" onClick=onClick={this.props.delete}>
Delete
</button>
</div>
</div>
)
}
}
export default Item;
逻辑:我的Cart
组件将从Node.js的端点获取数据。它是一个对象数组,Cart
组件使用它来填充item
组件。 item
组件具有一个删除按钮,一旦触发,该按钮将发送要删除的项目的名称,并使用MongoDB的查询删除该项目。
但是,后端表明已成功删除它,但是父级Cart
组件仍呈现已删除的项目。我想找到一种删除物品后触发购物车重新渲染的方法。
编辑:
来自url的简单数据是一个像这样的对象数组:
[{ desc: 'Market', total: 4000, amount: 1 }
{ desc: 'Data', total: 17000, amount: 1 }]
handleDelete()中的响应是被称为axios的响应,格式如下:
{data: {…}, status: 200, statusText: "OK", headers: {…}, config: {…}, …}
config: {adapter: ƒ, transformRequest: {…}, transformResponse: {…}, timeout: 0, xsrfCookieName: "XSRF-TOKEN", …}
data: {express: Array(1)}
headers: {date: "Wed, 03 Oct 2018 18:30:02 GMT", etag: "W/"37-QxQ/lxfNH/fWEmtfXYAG1YLiA/E"", x-powered-by: "Express", content-length: "55", vary: "Accept-Encoding", …}
request: XMLHttpRequest {onreadystatechange: ƒ, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}
status: 200
statusText: "OK"
__proto__: Object
从response.data
,我得到express: Array(1)
,所以从response.data.express
,我实际上是在获取数据数组
@ Code-Apprentice的编辑后。现在的问题是,在完成第一个删除调用之后,第二个被调用的axios没有调用get invoke。我试图打印出我从第二个轴测仪得到的结果,并且它与第一个渲染的数据相同。
答案 0 :(得分:1)
要触发任何组件的重新呈现,可以调用this.setState()
。在这种情况下,您需要从cartData
中删除已删除的项目,并调用类似this.setState({cartData: updatedData});
的名称。 (确保映射到cartData
中的testData
而非render()
上。)
为此,您需要一个回调函数,该回调函数作为prop从Cart
传递到Item
。例如,将其命名为onDelete()
。该功能负责实现上一段中描述的逻辑。您可以通过以下两种方式之一来实现此目的:
从后端获取数据。这将为您提供数据库中项目的准确列表。
从this.state.cardData
中删除已删除的项目。这样比较快,因为您不必发出网络请求,但是可能会删除错误的项目,从而使组件的状态与后端数据库中的数据不同。
附录:
在当前版本中,您尝试使用以下代码行传递回调:
delete={this.handleDelete(item.desc)}
问题在于,当您在购物车数据中的每个商品上进行映射时,这会立即this.handleDelete()
调用。因此,每个项目均被删除。相反,您需要创建一个函数,该函数将在单击按钮时执行:
delete={() => this.handleDelete(item.desc)}
答案 1 :(得分:0)
因此,基本上,删除商品后,您需要更新购物车组件中的状态。为此,您可以再次获取数据或从购物车状态中仅删除该项目。在以下代码段中,handleDelete将从cartData中拼接该项并将其设置为state,该状态将触发组件渲染。
<Item
key={index}
desc={item.desc}
amount={item.amount}
total={item.total}
onDelete={this.handleDelete}
/>
handleClick(e){
e.preventDefault()
axios({method: "post", url: "/remove", data:{name: this.props.desc}}).then(() => {this.props.handleDelete(this.props.desc)})
}
答案 2 :(得分:0)
您应该在父组件中创建一个带有项ID的函数,该函数将负责发出删除请求,并在响应返回后从数组和setState中删除父项的已删除项。 将此函数发送到父渲染方法上的每个项目。 在子组件中,当用户单击删除按钮时,将从父组件调用传递的函数,并将ID传递给该函数。