我编写了一个UI元素作为功能组件,该元素使用React的userReducer
钩子,并且似乎可以正常运行。
useReducer
引用了我编写的函数(想象中称为reducer
):
const [state, dispatch] = React.useReducer(reducer, inputData,
(inputData) => initialState(inputData));
有state
数据,由化简函数输入和输出;还有依赖于state
的“托管” UI元素,例如...
return (
<div>
<div>
{state.elements.map(getElement)}
</div>
<ShowHints hints={state.hints} inputValue={state.inputValue} />
</div>
);
...这很正常。
我担心的是reducer
函数不是纯函数。
副作用是存在一个<input>
元素,其状态由以下其中之一控制:
const inputRef = React.createRef<HTMLInputElement>();
<input>
控件仅是半托管的,如下所示:
<input type="text" ref={inputRef} onKeyDown={handleKeyDown} onChange={handleChange}
onKeyDown
和onChange
事件是分派给reducer的动作(很好),但是reducer传递给HTMLInputElement
实例(即inputRef.current
值)为输入参数,然后reducer设置该HTMLInputElement
的属性以使其状态发生变化-而不是<input>
是一个完全托管的组件,其内容由reducer输出的状态定义
<input>
元素未得到完全管理的原因是,我需要控制start
和end
中的选择范围(即<input>
和inputRef.current
)不仅是文本值。
问题:
state
属性)并返回新的start
值end
元素的<input type="text">
和<input>
属性,例如一种定义start
元素的方法,以便其end
和state
的值由化简器返回的<div>
控制?(我认为@Fyodor's answer below回答了第二个问题,但我仍然不确定第一个问题)。
是什么决定了要在HTML元素上设置的值?传入的使用信息还是包含逻辑?
该组件的设计和源代码很长shown here。
这是一个复杂的“组件”,它使用几个元素来实现-几个<span>
,几个<svg>
,一些可点击的<input>
和{{1} }元素。
给出减速器作为其输入参数:
<input>
实例(可以从中读取<input>
的当前状态)几个事件处理程序或操作中的两个是onKeyDown
的{{1}}和onChange
事件,因此<input>
的当前状态被传递给化简器当发生更改<input>
状态的事件时。
答案 0 :(得分:1)
技术上,还原剂可能在其中具有不同的副作用。我认为这不是一个好的做法,至少是由于关注点之间的分离不良(可以期望reducer仅基于操作产生新的状态,而不会改变其他状态)。 (很抱歉,我提出自己的见解,似乎使用了useReducer
中的副作用,例如here)。同样在Redux中,所有副作用都移至action creators。
对于您的特定问题,我建议您将inputRef
突变移动到单独的useEffect
钩子上,这又取决于下面的状态
useEffect (() => {
inputRef.currect // do work with inputRef
}, [state]); // make dependent from state
sample是useEffect
依赖形式state
您还可以将useEffect
移至custom hook,以使代码可重复使用,如下所示(未经测试,用作提示)
function mutateRef (inputRef: React.RefObject<HTMLInputElement>, state: /* type of state */) {
useEffect (() => {
inputRef.currect // do work with inputRef
}, [state, inputRef]);
}