我正在使用rededcer HOC并注意到这种行为: 在单击处理程序上调用此方法,例如:
import React from 'react'
import { withReducer } from 'recompose'
import { compose } from 'ramda'
export default compose(
withReducer('state', 'dispatch', (state, { value }) => {
console.log(value)
return { ...state, value }
}, { value: 'zero' })
)((props) => {
const { dispatch, state } = props,
onClick = () => {
console.log('Hello')
dispatch({ value: 'one' })
dispatch({ value: 'two' })
dispatch({ value: 'three' })
console.log('World')
}
return (
<div>
<div>{state.value}</div>
<button onClick={onClick}>Click me</button>
</div>
)
})
它会产生
您好
世界
一个
2
3
这意味着reduce函数是异步调用的。 将其称为异步而不是立即将更改应用于存储的理由是什么?
答案 0 :(得分:4)
reducer是异步调用的,因为我们只能使用setState
来更新树,而setState
是异步的。
如果我们同步调用reducer,我们需要在某处保存新状态,然后调用setState
并从我们保存它的位置异步获取新状态。最后,您的树仍然会异步更新。
这就是为什么重构withReducer()
与redux略有不同。您可以认为withReducer
是redux + react-redux的connect()
的简化版本。
答案 1 :(得分:3)
在这种情况下,dispatch实际上是vanilla API方法setState
的包装器。
React异步实现setState
,因为出于性能原因,状态转换有时会被批处理。
根据React docs:
setState()不会立即改变this.state但会创建挂起状态转换....无法保证对setState的调用进行同步操作,并且可以对调用进行批处理以获得性能提升。