【发布时间】:2021-09-03 17:02:52
【问题描述】:
我正在创建一个反应组件:TxtEditor
在编辑器内部,有一个useReducer 用于操作文本的钩子:
APPEND => 更改当前文本。
UPPERCASE => 转换大写字母。
但是reducer函数不是纯函数。存在一些依赖关系:props.disabled => 忽略所有 reducer 操作。props.onTxtChanged => 将在文本修改后执行。
所以我在函数组件内部创建了reducer函数。
这对useReducer 来说是个问题,因为每次渲染组件时,总是会重新创建一个具有不同引用的新的相同函数。
从而使useReducer 在下一次渲染时执行reducer 函数两次 - 并触发props.onTxtChanged 两次。我不知道为什么要这样做。
然后为了解决这个问题,我用useCallback包裹了reducer函数。
它似乎工作,但不是。因为props.onTxtChanged 可能由用户使用an inline function 传递。并且函数总是被重新创建(相同但引用不同),从而使useCallback 无用。
最后我在函数组件外部创建了一个reducer函数。
该功能通过引用始终相同,并使useReducer正常工作。
为了注入依赖项,我做了一个 HACK 像这样:
const [state, dispatch] = useReducer(txtReducer, /*initialState: */{
text : 'hello',
props : props, // HACK: a dependency is injected here
});
state.props = props; // HACK: a dependency is updated here
所以props可以在reducer函数中访问:
const txtReducer = (state, action) => {
const props = state.props;
if (props.disabled) return state; // disabled => no change
}
它可以工作,但它包含一个 hack。
我想要以专业的方式来做这些事情。
你有什么建议吗?
【问题讨论】:
标签: reactjs use-reducer