当状态改变时从状态变量更新数据库
Update database from state variable when state changes
我想做的是在按下保存按钮时使用状态变量更新我的数据库。在保存处理程序中,一个新值被添加到 this.state.saved 列表并调用了一个 updataDatabase 函数。问题是按下按钮时 setState 不会更新状态变量,因此数据库中没有任何更新。我的问题是:如何使 setState 更新组件以便更新数据库?
这是我的代码
class Articles extends Component{
constructor(props){
super(props);
this.state = {
check:false,
saved:[]
}
this.handleSave = this.handleSave.bind(this)
}
async componentDidMount(){
savedArticles = this.props.article.saved
this.setState({
check:this.props.article.check,
saved:this.props.article.saved
})
}
async updateDataBase(){
let updates = {
body:{
userName:this.props.article.user,
userEmail:this.props.article.email,
userPhone:this.props.article.phone,
savedArticles:this.state.saved,
userInterests:this.props.article.interestList,
}
}
console.log(updates)
return await API.put(apiName,path,updates);
}
handleSave () {
const urlList = [];
let article = {};
for(let i=0; i<this.state.saved.length; i++){
urlList.push(this.state.saved[i].url)
}
if(!urlList.includes(this.props.article.url)){
article = {
url:this.props.article.url,
title:this.props.article.title,
image:this.props.article.urlToImage,
author:this.props.article.author,
check:true,
}
savedArticles.push(article)
this.setState({
check: true,
saved:[...this.state.saved,article]
})
this.updateDataBase();
}
}
render()
{
console.log(this.state.check)
return (
<div className="item">
<div className="card">
<img src={this.props.article.urlToImage} alt="No available image" width="100%" height="200px"></img>
<div>
<h5 className="card-title">{this.props.article.title}</h5>
<p className="card-text">{this.props.article.author}</p>
<a href={this.props.article.url} target="_blank" id="articleLink" className="btn btn-primary"><FontAwesomeIcon icon="external-link-alt" /> See full article</a>
{this.state.check?(
<button disabled={true} id="buttonsArticle" className="btn btn-primary"><FontAwesomeIcon icon="check" /> Saved</button>
):(
<button onClick={this.handleSave.bind(this)} id="buttonsArticle" className="btn btn-primary"><FontAwesomeIcon icon="save" /> Save Article</button>
)}
</div>
</div>
<div className="divider"></div>
</div>
)
}}
问题在于您的代码是 运行 同步的。您正在设置状态然后调用 this.updateDataBase();
但状态不会在该上下文中更新。状态实际更新和后续渲染发生在这之后。你可以把它想象成一个你调用 setState
的队列,它注意到状态需要更新,但队列中的其他所有内容都必须首先执行。
看看这个:https://codesandbox.io/s/32n06zlqop?fontsize=14如果你点击按钮,它会立即注销错误的状态,然后在componentDidUpdate
中再次注销,你可以看到那个状态已经设置好了。
所以你有两个选择,你可以在 componentDidUpdate
生命周期方法中调用更新数据库函数。此函数在每次渲染后调用,可由状态更改触发。
或者,您可以将第二个回调函数参数传递给设置状态,在实际设置状态后调用。这可能是最优雅的版本:
this.setState({
check: true,
saved:[...this.state.saved, article]
}, this.updateDataBase)
我想做的是在按下保存按钮时使用状态变量更新我的数据库。在保存处理程序中,一个新值被添加到 this.state.saved 列表并调用了一个 updataDatabase 函数。问题是按下按钮时 setState 不会更新状态变量,因此数据库中没有任何更新。我的问题是:如何使 setState 更新组件以便更新数据库? 这是我的代码
class Articles extends Component{
constructor(props){
super(props);
this.state = {
check:false,
saved:[]
}
this.handleSave = this.handleSave.bind(this)
}
async componentDidMount(){
savedArticles = this.props.article.saved
this.setState({
check:this.props.article.check,
saved:this.props.article.saved
})
}
async updateDataBase(){
let updates = {
body:{
userName:this.props.article.user,
userEmail:this.props.article.email,
userPhone:this.props.article.phone,
savedArticles:this.state.saved,
userInterests:this.props.article.interestList,
}
}
console.log(updates)
return await API.put(apiName,path,updates);
}
handleSave () {
const urlList = [];
let article = {};
for(let i=0; i<this.state.saved.length; i++){
urlList.push(this.state.saved[i].url)
}
if(!urlList.includes(this.props.article.url)){
article = {
url:this.props.article.url,
title:this.props.article.title,
image:this.props.article.urlToImage,
author:this.props.article.author,
check:true,
}
savedArticles.push(article)
this.setState({
check: true,
saved:[...this.state.saved,article]
})
this.updateDataBase();
}
}
render()
{
console.log(this.state.check)
return (
<div className="item">
<div className="card">
<img src={this.props.article.urlToImage} alt="No available image" width="100%" height="200px"></img>
<div>
<h5 className="card-title">{this.props.article.title}</h5>
<p className="card-text">{this.props.article.author}</p>
<a href={this.props.article.url} target="_blank" id="articleLink" className="btn btn-primary"><FontAwesomeIcon icon="external-link-alt" /> See full article</a>
{this.state.check?(
<button disabled={true} id="buttonsArticle" className="btn btn-primary"><FontAwesomeIcon icon="check" /> Saved</button>
):(
<button onClick={this.handleSave.bind(this)} id="buttonsArticle" className="btn btn-primary"><FontAwesomeIcon icon="save" /> Save Article</button>
)}
</div>
</div>
<div className="divider"></div>
</div>
)
}}
问题在于您的代码是 运行 同步的。您正在设置状态然后调用 this.updateDataBase();
但状态不会在该上下文中更新。状态实际更新和后续渲染发生在这之后。你可以把它想象成一个你调用 setState
的队列,它注意到状态需要更新,但队列中的其他所有内容都必须首先执行。
看看这个:https://codesandbox.io/s/32n06zlqop?fontsize=14如果你点击按钮,它会立即注销错误的状态,然后在componentDidUpdate
中再次注销,你可以看到那个状态已经设置好了。
所以你有两个选择,你可以在 componentDidUpdate
生命周期方法中调用更新数据库函数。此函数在每次渲染后调用,可由状态更改触发。
或者,您可以将第二个回调函数参数传递给设置状态,在实际设置状态后调用。这可能是最优雅的版本:
this.setState({
check: true,
saved:[...this.state.saved, article]
}, this.updateDataBase)