我写了一个 UI 元素作为一个函数组件,它使用 React 的userReducer
钩子,它似乎运行没有错误。
useReducer
引用我写的一个函数(想象地称为reducer
):
const [state, dispatch] = React.useReducer(reducer, inputData,
(inputData) => initialState(inputData));
有state
reducer函数输入输出的数据;并且有一些“托管”的 UI 元素取决于state
...
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
和事件是分派给reducer的onChange
动作(这很好),但是reducer将HTMLInputElement
实例(即inputRef.current
值)作为输入参数传递,reducer设置它的属性HTMLInputElement
来改变它的状态——而不是<input>
存在一个完全托管的组件,其内容由 reducer 输出的状态定义。
<input>
元素不是完全管理的原因是我需要控制选择范围(即start
和end
),<input>
而不仅仅是它的文本值。
问题:
- 以这种方式不纯的 reducer 函数是否可以(例如,尽管存在问题或显着但没有错误)?
- 它仅取决于其输入参数,因此是可重复的
- 但它会改变某些东西(即
inputRef.current
属性)并返回新state
值
- 减速器是否有另一种方法来控制元素的
start
和end
属性<input type="text">
,例如,一种定义<input>
元素的方法,使其start
和end
值state
由减速器返回的他控制?
(我认为@Fyodor 下面的回答回答了第二个问题,我仍然不确定第一个问题)。
什么决定了要在 HTML 元素上设置的值?传入的使用信息是否包含逻辑?
组件的设计和源代码显示在这里,而且相当长。
它是一个复杂的“组件”,它使用几个元素来实现——几个<div>
s、几个<span>
s、一些可点击<svg>
的 s 和<input>
元素。
给出了减速器,作为它的输入参数:
- 之前的“状态”
- 当前
<input>
实例(它可以从中读取 的当前状态<input>
) - 由事件处理程序创建的“动作”
几个事件处理程序或动作中的两个是onKeyDown
和的onChange
事件,<input>
因此<input>
当有一个事件改变<input>
.