在以下代码中,设置状态后,setState方法的回调不会像预期的那样执行。如果你检查控制台,你会明白我的意思。console.log读取的状态不是更新的状态。它总是前一个(你可以通过点击读取数组按钮来检查这个),但是根据反应文档:
setState()的第二个参数是一个可选的回调函数,它将在setState完成并重新呈现组件后执行。通常,我们建议对此类逻辑使用componentDidUpdate()。
虽然我知道建议使用componentDidUpdate,但我很好奇为什么它不能按预期工作,或者我是否阅读了错误的文档。通过“一旦设置状态完成”,我理解它在新状态保存后执行。
class StateAsync extends React.Component {
constructor(props) {
super(props)
this.state = {
items: [
{ text: "JavaScript" },
{ text: "React" },
{ text: "JSFiddle" },
{ text: "Awesome" }
],
selectedItems: []
}
this.handleSelect = this.handleSelect.bind(this);
this.test = this.test.bind(this);
}
handleSelect(e) {
let selectedId = this.state.items[e.target.id].text;
let clone = [...this.state.selectedItems];
if(e.target.checked == false) {
console.log("Removing item.");
clone = clone.filter(item => item !== selectedId);
this.setState({
selectedItems: clone
}, console.log("Remove callback result is: " + this.state.selectedItems)); //-- the callback does not execute AFTER the state is set
}else{
this.setState({
selectedItems: [...this.state.selectedItems, selectedId]
}, console.log("Add callback result is: " + this.state.selectedItems)); //-- callback gets executed before the state is set
console.log("Item added.");
}
}
test(e) {
e.preventDefault();
console.log(this.state.selectedItems);
}
render() {
return (
<div>
<span onClick={this.test} className="d-none d-md-block"><button className="btn btn-dim btn-outline-light">Read Array</button></span>
<ol>
{this.state.items.map((item,index) => (
<li key={index}>
<label>
<input type="checkbox" onChange={this.handleSelect} id={index}/>
<span>{index} - {item.text}</span>
</label>
</li>
))}
</ol>
<span id="readout">
</span>
</div>
)
}
}
ReactDOM.render(<StateAsync />, document.querySelector("#app"))
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
li {
margin: 8px 0;
}
h2 {
font-weight: bold;
margin-bottom: 15px;
}
.done {
color: rgba(0, 0, 0, 0.3);
text-decoration: line-through;
}
input {
margin-right: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
这里还有一个代码:
https://codepen.io/nicholas_cb/pen/VweXoVa?editors=0010
那么,问题是setState方法中的回调是否在setState完成后执行,还是在同一时间/之前执行?
回调确实在状态更改后执行。
问题是您没有添加回调。
setState(updater, [callback])
this.setState(
{ selectedItems: clone },
// closure on this.state.selectedItems
() => console.log("Remove callback result is: " + this.state.selectedItems)
);
这是因为您没有将回调传递给setState()方法,而是直接传递控制台。log()语句。
您需要这样做:
this.setState({
selectedItems: clone
}, () => {
console.log("Remove callback result is: " + this.state.selectedItems
}); //-- the callback does not execute AFTER the state is set
您正在立即执行控制台日志,并将其返回值(未定义)作为回调传递。
这就是为什么您记录了当前状态,并且没有任何东西(未定义的
作为回调)需要在更新后的状态下执行。
相反,您需要传递一个回调函数,该函数反过来调用控制台日志:
this.setState({
selectedItems: clone
}, () => console.log("Remove callback result is: " + this.state.selectedItems));
在async-nature-of-setState中我们已经提到过, setState其实是异步的. 因为出于性能优化考虑, React会将多次setState做一次批处理. 于是setState并不会在被调用之后立即改变我们的state. 这就意味着你并不能依赖于在调用setState方法之后state, 因为此时你并不能确认该state更新与否. 当然针对这个问题我们也有解决办法—用前一个st
当react组件状态发生更改时,将调用render方法。因此,对于任何状态更改,都可以在呈现方法体中执行操作。那么setState回调是否有特定的用例?
本文向大家介绍Lua中让回调函数支持回调对象方法的解决方法,包括了Lua中让回调函数支持回调对象方法的解决方法的使用技巧和注意事项,需要的朋友参考一下 在 Cocos2d-Lua 中,存在很多异步或延迟的操作,例如后台加载图片、等待一定时间执行代码等。这些功能的函数通常要求传入一个 function 作为参数。 但如果我们希望这种回调支持一个对象方法,就有点小困难了。因为 Lua 的对象方法在调用
本文向大家介绍jQuery Ajax Post 回调函数不执行问题的解决方法,包括了jQuery Ajax Post 回调函数不执行问题的解决方法的使用技巧和注意事项,需要的朋友参考一下 今天在写一个检查用户名的功能时,使用的是jQuery.post( url, [data], [callback], [type] )这个函数,但是发现其中的回调函数不能执行。 先来看看我的代码: 前台代码: 后台
问题内容: 我试图将一个函数传递给另一个函数,然后使传递的函数执行并传递给它一个变量。 这是我的代码: 我得到的错误是 错误是“无法将’String’的值类型转换为预期的参数类型’()’。我知道这是语法问题-只是不知道它应该是什么。 问题答案: Rob的答案是正确的,尽管我想分享一个简单的工作回调/完成处理程序的示例,但是您可以在下面下载示例项目并尝试使用的输入。 斯威夫特5: 重要说明:
我需要将json对象从匿名函数加载到变量实例。 本例中的实例未定义。 我敢肯定,解决方法很简单,但是新手在节点上找不到答案…:(