我已经阅读到reducer应该是纯函数。
那么我有2个问题:如果将其他setState与reducer链接在一起,该如何管理?以及如何处理诸如焦点HTML元素之类的DOM操作?
为了说明这一点,这是我的代码带有不纯的减速器:
const ActDeclaration = () => {
const [errors, setErrors] = useState({})
const refPersonType = useRef()
const reducer = (state, action) => {
switch (action.type) {
case "internalNumber":
return { ...newState, internalNumber: action.payload }
case "profile": {
setErrors({}) // HERE
const errors = hasErrors(newState, setErrors)
if (!isEmpty(errors)) {
setErrors(errors) // HERE
refPersonType.current.scrollIntoView({ // HERE
behavior: "smooth",
block: "start",
})
}
return newState
}
default:
return newState
}
}
const [state, dispatch] = useReducer(reducer, {})
我使用setErrors
修改一个负责显示/管理错误的状态变量。
这可能会产生副作用吗?实际上,reducer中的setErrors是否会触发重新渲染?
在reducer的内部状态中管理错误状态对我而言并不理想,因为setErrors
也由不依赖于reducer的Submit函数调用,这就是为什么我发现take除错误外,是个好主意。
第二个问题,ref
焦点。我怀疑这也是副作用。怎么处理呢?之所以这样,是因为我有一个按钮,在单击事件时,该按钮会调用dispatch函数,然后是reducer函数。因此,reducer似乎是进行重点工作的合适人选。
感谢您的想法!
答案 0 :(得分:0)
profile
操作似乎错误的位置来检查错误并同时滚动。
您可以在useEffect
内的reducer外部或事件处理程序内进行此操作,因为profile
不会进行任何状态操作。