gpt4 book ai didi

node.js - react 应用程序的状态与我数据库中的状态不一致?

转载 作者:太空宇宙 更新时间:2023-11-03 23:01:16 26 4
gpt4 key购买 nike

我正在开发一个小型杂货 list 应用程序。每当我提交表单时,我都会执行 axios 请求以将商品添加到数据库并更新我的“商品”状态以包含新的杂货商品。

问题是,除非我刷新页面,否则我的状态仍然显示一个空的“items”数组。 “items”数组的初始状态是从数据库中提取的,这是通过使用 componentDidMount 并在其中设置“items”的状态来实现的。

此外,在我的状态下,我有 currentUser ,它也是从数据库中提取的。如果我在添加第一个项目后尝试记录 this.state.currentUser.shoppingList,它将显示一个空数组,即使我可以看到服务器端日志表明该数组不为空。

这是我的代码:

**App Component**
import React from 'react';
import ListForm from './ListForm';
import * as helpers from '../helpers';

class App extends React.Component{
state = {
currentUser: {},
items: []
}

componentDidMount() {
console.log('Hello!');
helpers.fetchUser()
.then(data => {
this.setState({
currentUser: data,
items: data.shoppingList
}, () => {
console.log(this.state)
});
});
}

// Handle adding new items
onSubmit = (id, item) => {
this.setState({items: this.state.items.concat([item])});
helpers.addItem(id, item);
console.log(this.state);
}

// Handle deletion of items
onDelete = (id, deleteItem) => {
var shoppingList = this.state.currentUser.shoppingList;
var index = shoppingList.findIndex(x => x.name === deleteItem);

console.log(shoppingList);
helpers.removeItem(id, deleteItem);
}

render() {
return (
<div className="container row offset-4">
<div className="jumbotron col-sm-6">
<ListForm
currentUser={this.state.currentUser}
items={this.state.items}
onSubmit={this.onSubmit}
onDelete={this.onDelete}
/>
</div>
</div>
);
}
};

export default App;

Helpers.js

import axios from 'axios';

export const fetchUser = async () => {
const resp = await axios.get('/api/current_user');

return resp.data;
}

export const addItem = (id, newItem) => {
const resp = axios.post("/api/" + id + "/addItem", newItem);

return resp.data;
}

export const removeItem = (id, deleteItem) => {
const resp = axios.delete("/api/" + id + "/removeItem", {data: {item: deleteItem}});

return resp.data;
}

ListForm组件

import React from 'react';
import ListItem from './ListItem';

class ListForm extends React.Component {
state = {
value: ''
}

// Render content based on whether or not currentUser has been returned from
// our API request.
renderContent = () => {
const shoppingList = this.props.currentUser.shoppingList;
if(shoppingList === null || shoppingList === undefined) {
return (<h5>Loading List</h5>);
} else {
return (
<div>
{this.props.items.map((item, index) =>
<ListItem
{...item}
key={index}
id={index}
currentUser={this.props.currentUser}
onDelete={this.props.onDelete}
/>
)}
</div>
);
}
}

// Handle the submission of a new item to database and state.
handleSubmit = e => {
e.preventDefault();

this.props.onSubmit(this.props.currentUser._id, {name: this.state.value});
this.setState(prevState => ({value: ''}));
}

// Handle any changes within the input.
onChange = e => {
this.setState({value: e.target.value});
}

render() {
return (
<div className="col-xs-9">
<h3>Grocery List</h3>
<form className="form-control" onSubmit={this.handleSubmit}>
<input style={{display: "inline", width: "60%", height: "2em"}} className="form-control" type="text"
value={this.state.value}
onChange={this.onChange}
/>
<button className="btn btn-success btn-sm float-right">Add item</button>
</form>
<div style={{marginTop: "10%"}}>
{this.renderContent()}
</div>
</div>
);
}
}

export default ListForm;

ListItem 组件

import React from 'react';

const ListItem = props => {

// Handle delete item requests
const handleClick = event => {
var delItem = document.getElementById("btn" + props.id).textContent;

props.onDelete(props.currentUser._id, delItem);
}

return (
<div>
<li
style={{display: "inline"}} id={"btn" + props.id} key={props.id}>{props.name}
</li>
<button
style={{display: "inline"}} onClick={e => handleClick(e)} className="btn btn-danger btn-sm float-right">
Remove
</button>
<hr />
</div>
);
}

export default ListItem;

最佳答案

与每次组件状态更改时都会调用的 render() 不同,componentDidMount() 仅在组件“挂载”后调用一次,也就是说,在其 DOM Node 插入到 DOM 中之后。有关“已安装”术语的更多详细信息,您可能需要查看 Component Lifecyle Reference .

在您的代码中,添加项目将修改您客户端的 state.items (顺便说一下,不是 state.currentUser.shoppingList),以及您的 fetchUser 函数作为 componentDidMount 客户端方法的一部分仅被调用一次(引用: https://reactjs.org/docs/react-component.html#componentdidmount )。

换句话说,当您使用 addItem 将项目添加到数据库时,您的组件将不会与数据库更新同步,因为组件的状态不会更新以反射(reflect)数据库中发生的更改。后端。

如果您想将用户与数据库中的内容同步,那么您可以在将项目添加到数据库后调用fetchUser,如下所示:

  // Handle adding new items
onSubmit = (id, item) => {
this.setState({items: this.state.items.concat([item])});
helpers.addItem(id, item);
console.log(this.state);

helpers.fetchUser()
.then(data => {
this.setState({
currentUser: data,
items: data.shoppingList
}, () => {
console.log(this.state)
});
});
}

抱歉,我没有测试代码。也许更简洁的方法是“ promise ”您的 addItem 函数,就像您对 fetchUser 所做的那样。

希望这有帮助!

关于node.js - react 应用程序的状态与我数据库中的状态不一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47726063/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com