如果monthOffset = 12
,则条件将为true,如果yearOffset
,则将yearOffset = 2018
状态更新为2017。根据我已经阅读的react docs和其他答案,this.setState
中的回调函数会在状态更新后触发,但console.log()
仍会输出2018。我尝试了几种方法基于其他相关问题的答案实施此代码的方法,但是我的方法不起作用。我不确定为什么。
handleClick(e) {
const { monthOffset, yearOffset } = this.state
this.setState({ monthOffset: monthOffset - 1 })
if ( monthOffset - 1 === 11 ) { this.setState((prevState) => {
return { yearOffset: prevState.yearOffset - 1 } },
() => {console.log("yearOffset", yearOffset)}
)}
console.log("clicked")
}
答案 0 :(得分:4)
也许您可以通过以下方式简化逻辑,以避免多次调用<tr *ngFor="let number of [0,1,2,3,4]">{{number}}</tr>
可能导致意外结果:
setState
答案 1 :(得分:2)
文档说,回调始终有效,但是根据经验,它并不总是返回您所期望的结果。我认为这与在状态本身内部使用可变对象有关。
文档:https://reactjs.org/docs/react-component.html#setstate
您不能完全依赖回调。相反,您可以做的就是创建
var stateObject = this.state
对对象进行任何必要的更改:
stateObject.monthOffset -= 1
然后设置如下状态:
this.setState(stateObject);
这样,您就可以在nextState
中拥有stateObject
的副本
要澄清:要在设置状态之前进行所有评估,所以请这样做:
monthOffset -= 1
然后if (monthOffset === 12) yearOffset -=1;
然后var stateObj = {monthOffset: monthOffset, yearOffset: yearOffset}
然后this.setState(stateObj);
从文档中:“
setState()
的第二个参数是可选的回调函数,将在setState完成并重新呈现组件后执行。通常,我们建议改将componentDidUpdate()用于此类逻辑。“
因此,基本上,如果您想获取下一个状态,则应该在调用setState()
的函数中包含该状态的副本,或者应该从nextState
获取componentDidUpdate
>
后续考虑:作为参数传递给setState()
的所有内容均通过引用传递(而不是通过值传递)。因此,如果您在状态内以及在对SearchFilters: {}
的调用中有一个对象setState()
,则您有
setState({SearchFilters: DEFAULT_SEARCH_FILTERS}); // do not do this
您可能已将SearchFilters
设置为DEFAULT_SEARCH_FILTERS
,以清除名为“搜索过滤器”的表单,但是实际上,您将DEFAULT_SEARCH_FILTERS
(常数)设置为{ {1}},清除您的SearchFilters
。
预期的行为?你告诉我。
答案 2 :(得分:1)
在React中调用setState
有两种流行的模式:对象setState
和"functional setState
"。 Functional setState is generally used when the current state(或“先前状态”,或您想称其为旧状态的任何内容)is invoked in the setState
call.之所以这样做是因为setState
是异步的,因此后续的setStates
可以有时会在React无法完成第一个setState
周期之前运行。
您在setState
调用中使用了现有状态,因此使用功能setState
是一个合适的地方。替换
this.setState({ monthOffset: monthOffset - 1 })
使用
this.setState(monthOffset => {return {monthOffset: monthOffset - 1}})
如果当我初次看到它时像我一样,您可能会想:“嗯?这与我有什么不同?”区别在于,当setState
传递给函数而不是对象时,它会将更新放入队列中,而不是通过通常的解析过程进行处理,从而确保事情按顺序进行。
或者您可能不会这样想;您实际上在第二个setState
调用中使用了功能setState
。在您的第一个中也使用它,可以确保一切正确排队。