Higher Order componnt does not dilver InputList

Viewed 33
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)

Above I created Higher order Component with React hooks and React FORM hook in order to render input List component. But I get the following error

Invalid hook call. Hooks can only be called inside of the body of a function component.

1 Answers

Your Higher Order Component (HOC) isn't returning a React component and the React hook logic isn't in a the React component you are trying to return.

HOCs typically have a signature that looks like this at a minimum:

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

HOCs are really just Higher Order Functions, but in the world of React it's a function that returns a React component. If the above "curried" view is a bit difficult to grok, perhaps this expanded view will help:

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

In your code's case you are missing the "inner" anonymous React component. Don't forget to add a React key to the components you are mapping so when elements are removed or the underlying field data array is sorted/mutated/etc that React's reconciliation process can function correctly, use the mapped item's id property.

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>
    );
  };
};

Edit higher-order-componnt-does-not-dilver-inputlist

Related