> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/web/get-started/faq/react-hooks-error.md).

# React Hooks Error

World's #1 PDF SDK Library for Web, Mobile, Server, Desktop

If you are seeing the error below when creating custom components in WebViewer, it is probably due to the fact that you are using React Hooks in your component, or using a library that uses React Hooks.

{% code lineNumbers="true" %}

```
Error: 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:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
```

{% endcode %}

To fix this error, refactor your component to be a class based component rather than a functional component.

Here is an example of a functional component that uses React Hooks:

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
const CustomButton = () => {
    useEffect(() => {
        console.log('test');
    }, []);

    return <button>Click me!</button>;
}

const newCustomElement = {
    type: 'customElement',
    dataElement: 'customElementButton',
    render: () => <CustomButton />
};

instance.UI.setHeaderItems(header => {
    header.push(newCustomElement);
});
```

{% endcode %}
{% endtab %}
{% endtabs %}

Here is an example of a class based component that does the same thing:

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
class CustomButton extends React.Component {
    componentDidMount() {
        console.log('test');
    }

    render() {
        return <button>Click me!</button>;
    }
}

const newCustomElement = {
    type: 'customElement',
    dataElement: 'customElementButton',
    render: () => <CustomButton />,
};

instance.UI.setHeaderItems(header => {
    header.push(newCustomElement);
});
```

{% endcode %}
{% endtab %}
{% endtabs %}

### The reason hooks don't work for custom component

In WebViewer we use a different instance of React than the one you are using in your app. For hooks to work, the React instance where the hook was declared and where it was rendered must be the same. This is a limitation of React mentioned here: <https://react.dev/warnings/invalid-hook-call-warning#duplicate-react>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/web/get-started/faq/react-hooks-error.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
