反应应用程序的状态是不是最新的,我在我的数据库中?

我正在制作一个小杂货清单应用程序。 每当我提交一个表单,我执行一个axios请求将项目添加到数据库,并更新我的“项目”状态,以包含新的杂货项目。

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

另外,在我的状态,我有当前的用户也从数据库中拉出。 如果在添加我的第一个项目之后尝试loginthis.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节点被插入到DOM之后,只调用一次。 有关“已安装”术语的更多详细信息,可能需要查看“ 组件生命周期参考” 。

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

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

如果您希望将用户与数据库中的数据同步,则可以在将项目添加到数据库之后调用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) }); }); } 

虽然我没有testing代码,对不起。 也许一个更清晰的方法是“promisify”你的addItem函数就像你为fetchUser做的。

希望这可以帮助!

而不是这个:

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

尝试这个:

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