实现一个 useInputControl
hook,用于管理受控输入值并跟踪其他表单输入状态,例如:
属性 | 跟踪 | 变为 true 的时间 | 变为 false 的时间 |
---|---|---|---|
已触及 | 如果输入已获得焦点然后失焦 | 当用户使输入失焦(焦点 -> 失焦) | 永不自动重置 |
脏 | 如果值之前已更改 | 当用户输入内容时 永不自动重置 | |
不同 | 如果值与原始值不同 | 当值与初始值不同 | 当值与初始值相同时 |
该 hook 返回的 handleX
函数旨在在 <input>
的相关事件处理程序上调用,以便 hook 按预期工作。
export default function Component() {const nameInput = useInputControl('Oliver');return (<form><div><label htmlFor="name">Name</label><inputid="name"value={nameInput.value}onChange={nameInput.handleChange}onBlur={nameInput.handleBlur}/></div><p>Touched: {nameInput.touched.toString()}</p><p>Dirty: {nameInput.dirty.toString()}</p><p>Different: {nameInput.different.toString()}</p><button type="submit" disabled={!nameInput.different}>Submit</button><button type="button" onClick={nameInput.reset}>Reset</button><form>);}
initialValue: string
: 输入的初始值该 hook 返回一个具有以下属性的对象:
value: string
: 输入的当前值dirty: boolean
: 用户是否至少修改过一次touched: boolean
: 输入是否已获得焦点并失焦different: boolean
: 值是否与初始值不同handleChange: (event: React.ChangeEvent<HTMLInputElement>) => void
: 一个更新输入值的函数handleBlur: (event: React.FocusEvent<HTMLInputElement>) => void
: 在输入失焦时调用的函数reset: () => void
: 一个将所有状态重置为初始值的函数实现一个 useInputControl
hook,用于管理受控输入值并跟踪其他表单输入状态,例如:
属性 | 跟踪 | 变为 true 的时间 | 变为 false 的时间 |
---|---|---|---|
已触及 | 如果输入已获得焦点然后失焦 | 当用户使输入失焦(焦点 -> 失焦) | 永不自动重置 |
脏 | 如果值之前已更改 | 当用户输入内容时 永不自动重置 | |
不同 | 如果值与原始值不同 | 当值与初始值不同 | 当值与初始值相同时 |
该 hook 返回的 handleX
函数旨在在 <input>
的相关事件处理程序上调用,以便 hook 按预期工作。
export default function Component() {const nameInput = useInputControl('Oliver');return (<form><div><label htmlFor="name">Name</label><inputid="name"value={nameInput.value}onChange={nameInput.handleChange}onBlur={nameInput.handleBlur}/></div><p>Touched: {nameInput.touched.toString()}</p><p>Dirty: {nameInput.dirty.toString()}</p><p>Different: {nameInput.different.toString()}</p><button type="submit" disabled={!nameInput.different}>Submit</button><button type="button" onClick={nameInput.reset}>Reset</button><form>);}
initialValue: string
: 输入的初始值该 hook 返回一个具有以下属性的对象:
value: string
: 输入的当前值dirty: boolean
: 用户是否至少修改过一次touched: boolean
: 输入是否已获得焦点并失焦different: boolean
: 值是否与初始值不同handleChange: (event: React.ChangeEvent<HTMLInputElement>) => void
: 一个更新输入值的函数handleBlur: (event: React.FocusEvent<HTMLInputElement>) => void
: 在输入失焦时调用的函数reset: () => void
: 一个将所有状态重置为初始值的函数总结一下返回的字段:
value
:当前的输入值touched
:输入是否已获得焦点然后失去焦点dirty
:该值之前是否已更改different
:该值是否与原始值不同让我们了解每个字段以及如何实现它们:
value
value
是一个使用 React 状态跟踪的布尔值。一个 handleChange
处理程序用于从输入的 change
事件 更新 value 状态。
touched
touched
是一个使用 React 状态跟踪的布尔值。当输入失去焦点时,它将被设置为 true
。由于 hook 不知道 <input>
元素何时失去焦点,我们返回一个 handleBlur
函数,该函数将值设置为 true
,用户将在 onBlur
事件处理程序中调用 handleBlur
函数。
dirty
touched
是一个使用 React 状态跟踪的布尔值。由于它在之前被更改时设置为 true
,因此 handleChange
是一个不错的选择。
different
此字段不需要状态,因为它是一个派生状态,可以通过比较初始值和当前 value
来计算。但是,不应针对 initialValue
参数进行比较,因为该值在重新渲染期间可能会有所不同!
相反,我们使用 useRef
跟踪第一个渲染的 initialValue
。为什么不是状态?因为 initialValueRef
在 hook 挂载后永远不会改变。
const different = initialValueRef.current !== value;
reset
函数此函数重置 hook 中的所有状态。只需使用其初始值调用各种状态设置器即可。要设置的初始值可以从 initialValueRef
获取。
import { ChangeEvent, useCallback, useRef, useState } from 'react';interface UseInputValueReturn {value: string;dirty: boolean;touched: boolean;different: boolean;handleChange: (event: ChangeEvent<HTMLInputElement>) => void;handleBlur: () => void;reset: () => void;}const defaultDirty = false;const defaultTouched = false;export default function useInputControl(initialValue: string,): UseInputValueReturn {const initialValueRef = useRef<string>(initialValue);const [value, setValue] = useState(initialValue);const [dirty, setDirty] = useState(defaultDirty);const [touched, setTouched] = useState(defaultTouched);const handleChange: UseInputValueReturn['handleChange'] = useCallback((event) => {setValue(event.currentTarget.value);setDirty(true);},[],);const handleBlur: UseInputValueReturn['handleBlur'] = useCallback(() => {setTouched(true);}, []);const reset = useCallback(() => {setValue(initialValueRef.current);setDirty(defaultDirty);setTouched(defaultTouched);}, []);// Derived from whether the value is different from the initial valueconst different = initialValueRef.current !== value;return {value,dirty,touched,different,handleChange,handleBlur,reset,};}
console.log()
语句将显示在此处。