高阶组件不会分散 InputList

IT技术 reactjs react-hooks higher-order-components
2021-05-13 08:13:34
export const HOC = (WrappedComponent) => {


  const { register, control, handleSubmit, reset, watch } = useForm({
    defaultValues: {
      test: [{ firstName: "Bill", lastName: "Luo" }]
    }
  });
  const { fields, append, prepend, remove } = useFieldArray({
    control,
    name: "test"
  });

  return (
    <form>
   
      <ul>
        {fields.map((item, index) => {
          return (
            <WrappedComponent
              item={item}
              removeindex={remove}
              index={index}
              {...register(`test.${index}.firstName`)}
            />
          );
        })}
      </ul>
      <section>
        <button
          type="button"
          onClick={() => {
            append({ firstName: "appendBill" });
          }}
        >
          Append
        </button>
      </section>
    </form>
  );
};
export default HOC 

const InputList = props => {

 
    return (
        <li key={props.item.id}>
         <input   {...props}  ></input>
         <button onClick={() => props.removeindex(props.index)} type="button" >Delete</button>
          
      </li>
        
    );
};
export default HOC(InputList)

上面我创建了带有 React 钩子和 React FORM 钩子的高阶组件,以呈现输入列表组件。但我收到以下错误

无效的钩子调用。钩子只能在函数组件的主体内部调用。

1个回答

您的高阶组件 (HOC) 没有返回 React 组件,并且 React 钩子逻辑不在您尝试返回的 React 组件中。

HOC 通常具有至少如下所示的签名:

const withHOC = WrappedComponent => props => <JSX />

HOC 实际上只是高阶函数,但在 React 的世界中,它是一个返回 React 组件的函数。如果上面的“咖喱”视图有点难以理解,也许这个扩展视图会有所帮助:

const withHOC = WrappedComponent => {
  // some HOC logic
  return props => {
    // some fancy component logic
    return (
      <WrappedComponent {...props} {/* ...HOC props? */} />
    );
  };
};

在您的代码的情况下,您缺少“内部”匿名 React 组件。不要忘记为您正在映射的组件添加一个 React 键,以便当元素被删除或底层字段数据数组被排序/变异/等 React 的协调过程可以正常运行时,使用映射项的id属性。

export const HOC = WrappedComponent => {
  return props => {
    const { register, control, handleSubmit, reset, watch } = useForm({
      defaultValues: {
        test: [{ firstName: "Bill", lastName: "Luo" }]
      }
    });

    const { fields, append, prepend, remove } = useFieldArray({
      control,
      name: "test"
    });

    return (
      <form>
        <ul>
          {fields.map((item, index) => (
            <WrappedComponent
              key={item.id} // <-- add React key for deletion reconciliation
              item={item}
              removeindex={remove}
              index={index}
              {...register(`test.${index}.firstName`)}
            />
          ))}
        </ul>
        <section>
          <button
            type="button"
            onClick={() => append({ firstName: "appendBill" })}
          >
            Append
          </button>
        </section>
      </form>
    );
  };
};

编辑高阶组件不做的输入列表