从 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:

Not working v7 Codesandbox

Working v6 Codesandbox

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}
  // [...]
/>

Here is the codesandbox.