skip to Main Content

I’m writing a package called "Formcomponent", with the help of React + React Bootstrap.

This is the index.tsx

/**
 * Renders a component for a form.
 */
import React from "react";
import Form from "react-bootstrap/Form";

/**
 * List of props
 * @returns
 */
interface FormcomponentProps {
  name: string;
}

export const Formcomponent = ({ name }: FormcomponentProps) => {
  return (
    <Form.Group controlId={name}>
      {/* input text */}
      <Form.Label>{name}</Form.Label>
      <Form.Control type="text" name={name} />
    </Form.Group>
  );
};

When I build it, I got in dist:

index.d.ts

/**
 * Renders a component for a form.
 */
import React from "react";
/**
 * List of props
 * @returns
 */
interface FormcomponentProps {
    name: string;
}
export declare const Formcomponent: ({ name }: FormcomponentProps) => React.JSX.Element;
export {};

and

index.js

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Formcomponent = void 0;
/**
 * Renders a component for a form.
 */
var react_1 = __importDefault(require("react"));
var Form_1 = __importDefault(require("react-bootstrap/Form"));
var Formcomponent = function (_a) {
    var name = _a.name;
    return (react_1.default.createElement(Form_1.default.Group, { controlId: name },
        react_1.default.createElement(Form_1.default.Label, null, name),
        react_1.default.createElement(Form_1.default.Control, { type: "text", name: name })));
};
exports.Formcomponent = Formcomponent;

I import in another React project in package.json as "@sineverba/form-component": "file:../../personali/npm-pkg-form-component", and in the App.jsx of React project I use it as

import * as React from "react";
import { Form } from "react-bootstrap";
import { Formcomponent } from "@sineverba/form-component";

export const App = () => {
  return (
    <Form>
      <Formcomponent name="ciao" />
    </Form>
  );
};

export default App;

But I got in console

Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: [...]

and

Uncaught TypeError: Cannot read properties of null (reading 'useMemo') at FormGroup.js:11:26

(FormGroup.js from react bootstrap is defined as

import * as React from 'react';
import { useMemo } from 'react';
import FormContext from './FormContext';
import { jsx as _jsx } from "react/jsx-runtime";
const FormGroup = /*#__PURE__*/React.forwardRef(({
  controlId,
  // Need to define the default "as" during prop destructuring to be compatible with styled-components github.com/react-bootstrap/react-bootstrap/issues/3595
  as: Component = 'div',
  ...props
}, ref) => {
  const context = useMemo(() => ({
    controlId
  }), [controlId]);
  return /*#__PURE__*/_jsx(FormContext.Provider, {
    value: context,
    children: /*#__PURE__*/_jsx(Component, {
      ...props,
      ref: ref
    })
  });
});
FormGroup.displayName = 'FormGroup';
export default FormGroup;

Update 1

In index.tsx (external component) I imported React as import * as React from "react"; but got same errors.

Update 2

I uploaded the repository here: https://github.com/sineverba/npm-pkg-form-component

Of course it is not published (yes), to test it can be cloned on local and used with "@sineverba/form-component": "file:../../personali/npm-pkg-form-component"

A small news. I tried to export a simply <p>Hello World</p> (so a simple HTML) and it works only if I use as name Formcomponent and not FormComponent (see the capital of C).

By the way, changing the name to Formcomponent and introducing the React Bootstrap Form, got same errors.

Update 3

I exported from my component a simply input tag and it works.
Probably some weird errors with React Bootstrap library used as imported from another component.

2

Answers


  1. Check first that both the React project and the Formcomponent library are using compatible versions of React and React Bootstrap. Mismatched versions can lead to errors like Invalid hook call.

    In your project, look into the package.json file to find the version of React you are using. It would be listed under the dependencies section, e.g.,

    "dependencies": {
        "react": "^18.2.0",
        "react-bootstrap": "^2.9.0",
        ...
    }
    

    Similarly, in the Formcomponent package, look into its package.json file to find the version of React it is using, e.g.,

    "dependencies": {
        "react": "^18.2.0",
        "react-bootstrap": "^2.9.0",
        ...
    }
    

    Compare the version numbers to see if they match. If there is a discrepancy, it could lead to issues.

    Declare React and React Bootstrap as peer dependencies in the Formcomponent package to avoid duplicate installations. This tells consumers of your library which versions of React and React Bootstrap they should use, without including them in your library bundle.

    "peerDependencies": {
      "react": "^18.2.0",
      "react-bootstrap": "^2.9.0"
    }
    

    You can also run the command npm ls react or yarn list react (depending on whether you are using npm or yarn).
    This command will list all the installed versions of React in your project and where they are being used.


    Note: The import statement for Formcomponent in your project does not match the export statement in the Formcomponent package. The import statement is import { Formcomponent } from "@sineverba/form-component"; but in your project you are trying to use it as <FormComponent name="ciao" /> which should instead be <Formcomponent name="ciao" /> (case-sensitive).

    And instead of using the file path in package.json, consider using npm link or yarn link to link to your local Formcomponent package during development. This will allow you to test the library in a more realistic environment, similar to how it will be used when published.


    I exported from my component a simply input tag and it works.
    Probably some weird errors with React Bootstrap library used as imported from another component.

    If exporting a simple HTML input tag works, but exporting a component from React Bootstrap does not, suggests that there might be an issue with how React Bootstrap is being used or integrated within the Formcomponent package.

    If React Bootstrap is not already declared as a peer dependency in the Formcomponent package, it would be good to do so. That way, Formcomponent will use the React Bootstrap version installed in the consuming project, which can help avoid version conflicts and duplicate dependencies.

    "peerDependencies": {
        "react-bootstrap": "^version"
    }
    

    And make sure the React Bootstrap components are being imported correctly in the Formcomponent package. Double-check the import statements and compare them with the documentation for React Bootstrap to ensure accuracy.

    Look into the specific error messages and stack traces provided in the console to pinpoint where the error originates. That could provide clues as to what is going wrong when React Bootstrap components are used.

    Login or Signup to reply.
  2. In your Formcomponent.tsx, import Form and FormLabel from react-bootstrap and use them accordingly:

    tsx:

    import React from 'react';
    import { Form, FormControl, FormGroup } from 'react-bootstrap';
    
    interface FormcomponentProps {
      name: string;
    }
    
    export const Formcomponent = ({ name }: FormcomponentProps) => {
      return (
        <FormGroup controlId={name}>
          <Form.Label>{name}</Form.Label>
          <FormControl type="text" name={name} />
        </FormGroup>
      );
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search