从 v6 迁移到 v7
Migration from v6 to v7
我今天升级到react-hook-form v7了。一切都很顺利,直到我遇到一些使用 ref 属性的遗留代码。
在版本 6 中这完美地工作
<ToggleSwitch toggleName='ifMonitoring'
ref={(e) => {
monitoring.current = e;
register(e);
}}
/>
但是在版本 7 中不再使用 ref,取而代之的是 {...register('ifMonitoring')}
。这在整个应用程序中工作正常,但上面的示例只是一个不起作用的示例。
我试图搜索类似的问题,但无济于事。
有人可以帮忙吗?
编辑:
添加更多代码以更好地理解这一点
function Edit() => {
const monitoring = useRef(null);
return <Controller name='monitoring' control={control} render={({ field: { ref }, fieldState }) => <ToggleSwitch ref={ref} checked={portInfo.isMonitored} />} />
ToggleSwitch 是具有自己状态的组件。它确实有 onChange 但要保持其状态
const ToggleSwitch = forwardRef((props, ref) => {
const [toggleCheck, setToggleCheck] = useState(props.checked);
const handleOnChange = (e) => {
setToggleCheck((prevState) => !prevState);
if (props.onChange) {
props.onChange(props.entry._id);
}
};
return (
<div className={`toggle btn btn-sm`}>
<input type='checkbox' defaultChecked={toggleCheck} onChange={handleOnChange} ref={ref} name={`toggle`} />
<div className='toggle-group'>
<label htmlFor={`toggle`} className={`btn btn-success`}>
In Use
</label>
<label htmlFor={`toggle`} className={`btn btn-danger`}>
Not in Use
</label>
<span className={`toggle-handle btn btn-light btn-xs`}></span>
</div>
</div>
);
编辑 2 和 3:
ref
实际上还在那里,它由 register
返回,其中包括我们传播的其他内容。
有an example on the React Hook Form documentation to share ref usage.
你可以这样做:
const { ref, ...rest } = register("ifMonitoring");
<ToggleSwitch
{...rest}
ref={(e) => {
monitoring.current = e;
ref(e);
}}
/>;
编辑
在您的特定情况下,您正在将 ...rest
传递给 ToggleSwitch
组件,但该组件不会将这些道具转发给内部输入(除了您在支柱).
这里的问题尤其来自 onChange
,它是 rest
变量中元素的一部分。因为你也有你的自定义 onChange
,你可以将你的和 React Hook Form 的一个结合起来。
因此,在您的主要组件中,您可以像这样传递 rest
属性:
<ToggleSwitch
inputProps={rest}
ref={(e) => {
ref(e);
inUseRef.current = e;
}}
// [...]
/>
而在你的ToggleSwitch
组件中,你可以在你自己的函数中调用RHF的onChange
,将input props传递给input,然后再传递你的onChange
函数。
const handleOnChange = (e) => {
setToggleCheck((prevState) => !prevState);
if (inputProps.onChange) {
inputProps.onChange(e);
}
};
// [...]
<input
// [...]
{...inputProps}
onChange={handleOnChange}
ref={ref}
// [...]
/>
我今天升级到react-hook-form v7了。一切都很顺利,直到我遇到一些使用 ref 属性的遗留代码。
在版本 6 中这完美地工作
<ToggleSwitch toggleName='ifMonitoring'
ref={(e) => {
monitoring.current = e;
register(e);
}}
/>
但是在版本 7 中不再使用 ref,取而代之的是 {...register('ifMonitoring')}
。这在整个应用程序中工作正常,但上面的示例只是一个不起作用的示例。
我试图搜索类似的问题,但无济于事。
有人可以帮忙吗?
编辑:
添加更多代码以更好地理解这一点
function Edit() => {
const monitoring = useRef(null);
return <Controller name='monitoring' control={control} render={({ field: { ref }, fieldState }) => <ToggleSwitch ref={ref} checked={portInfo.isMonitored} />} />
ToggleSwitch 是具有自己状态的组件。它确实有 onChange 但要保持其状态
const ToggleSwitch = forwardRef((props, ref) => {
const [toggleCheck, setToggleCheck] = useState(props.checked);
const handleOnChange = (e) => {
setToggleCheck((prevState) => !prevState);
if (props.onChange) {
props.onChange(props.entry._id);
}
};
return (
<div className={`toggle btn btn-sm`}>
<input type='checkbox' defaultChecked={toggleCheck} onChange={handleOnChange} ref={ref} name={`toggle`} />
<div className='toggle-group'>
<label htmlFor={`toggle`} className={`btn btn-success`}>
In Use
</label>
<label htmlFor={`toggle`} className={`btn btn-danger`}>
Not in Use
</label>
<span className={`toggle-handle btn btn-light btn-xs`}></span>
</div>
</div>
);
编辑 2 和 3:
ref
实际上还在那里,它由 register
返回,其中包括我们传播的其他内容。
有an example on the React Hook Form documentation to share ref usage.
你可以这样做:
const { ref, ...rest } = register("ifMonitoring");
<ToggleSwitch
{...rest}
ref={(e) => {
monitoring.current = e;
ref(e);
}}
/>;
编辑
在您的特定情况下,您正在将 ...rest
传递给 ToggleSwitch
组件,但该组件不会将这些道具转发给内部输入(除了您在支柱).
这里的问题尤其来自 onChange
,它是 rest
变量中元素的一部分。因为你也有你的自定义 onChange
,你可以将你的和 React Hook Form 的一个结合起来。
因此,在您的主要组件中,您可以像这样传递 rest
属性:
<ToggleSwitch
inputProps={rest}
ref={(e) => {
ref(e);
inUseRef.current = e;
}}
// [...]
/>
而在你的ToggleSwitch
组件中,你可以在你自己的函数中调用RHF的onChange
,将input props传递给input,然后再传递你的onChange
函数。
const handleOnChange = (e) => {
setToggleCheck((prevState) => !prevState);
if (inputProps.onChange) {
inputProps.onChange(e);
}
};
// [...]
<input
// [...]
{...inputProps}
onChange={handleOnChange}
ref={ref}
// [...]
/>