We have made our own npm-package and I'm now working on a time out alert. To get the time out to work right I need to have it inside a useEffect but I get error: react.development.js:1465 Uncaught Error: Invalid hook call. .
The file in the component in the npm package is in typescript but I don´t think that´s the problem. .tsx:
import * as React from "react";
/**
* @param {string} close_button_title default "Stäng"
* @param {"top" | "bottom"} alert_position fixes the alert to bottom och top
* @param {"warning" | "success" | "danger" | "error"} alert_type success as default
* @param {any} alert_text plain text or html elements whit text, if empty/null/false the Alert is not shown
* @param {any} set_alert_text the set state (hook) for alert_test (ex: setAlertText), must be right to close alert both whit timeout and the close btn
* @param {boolean} alert_inline used to get alert message inline in modal
*/
const TimeOutAlert = (props: {
close_button_title: string;
alert_position?: "top" | "bottom";
alert_type?: "warning" | "success" | "danger" | "error";
message_wrapper_id?: string;
alert_text: any;
set_alert_text: any;
alert_inline?: boolean;
}) => {
const {
close_button_title = "Stäng",
alert_position = "top",
alert_type = "success",
message_wrapper_id = null,
alert_text,
set_alert_text,
alert_inline = false,
} = props;
React.useEffect(() => {
if (alert_text) {
setTimeout(() => {
set_alert_text("");
}, 15 * 1000);
}
}, [alert_text]);
let alertClasses = `message__alert__fixed--${alert_position}`;
if (alert_inline) {
alertClasses = "message__alert--inline";
}
if (alert_text) {
return (
<div
className={`message__alert--${alert_type} ${alertClasses}`}
id={message_wrapper_id}
>
{close_button_title && (
<button
className="icon icon--140 button--icon message__alert__button__close"
title={close_button_title}
onClick={() => set_alert_text("")}
>
close
</button>
)}
{alert_text}
</div>
);
}
return null;
};
export default TimeOutAlert;
index.ds
import TimeOutAlert from "./TimeOutAlert";
import OneMorefrom "./OneMore";
import Some "./Some";
import Else from "./Else";
export {
TimeOutAlert,
OneMore,
Some,
Else,
};
If I remove the useEffect, it works but then the time out don´t work as it should. When I use the package I import the component I want´t to use in my jsx-file or tsx-file. I have made ten or something components but have not used hooks in any of them except for this one.
Where I use the components App.jsx:
import React, { useState } from "react";
import { TimeOutAlert } from "our-npm-package";
export default () => {
const [message, setMessage] = useState("Alert meddelande");
return (
<>
<TimeOutAlert alert_text={message} set_alert_text={setMessage} />
I´m using react hooks in the main projects where I import this npm package so I usually know what´s the problem is but I don´t know way it´s not working now. I don´t usually use typescript, it´s just in the npm package to get intellisense when using it but I still think that it´s react thats the problem. But I could be wrong.
EDIT:
It's the useEffect that causes the error, useState throws the same error (tried to use that for changing the alertclass).
I have used this kind of timeouts in multiple projects that's why I want it in our react-components npm-package.
The full error message in the console:
Uncaught 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:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app
See ... for tips about how to debug and fix this problem.at resolveDispatcher (react.development.js:1465)
at Object.useEffect (react.development.js:1508)
at TimeOutAlert (TimeOutAlert.js:14)
at renderWithHooks (react-dom.development.js:14803)
at mountIndeterminateComponent (react-dom.development.js:17482)
at beginWork (react-dom.development.js:18596)
at HTMLUnknownElement.callCallback (react-dom.development.js:188)
at Object.invokeGuardedCallbackDev (react-dom.development.js:237)
at invokeGuardedCallback (react-dom.development.js:292)
at beginWork$1 (react-dom.development.js:23203)