I have a react application built for production and being served by a node/express server.
I have started the server locally and also deployed it to heroku and render.com
On all these systems, Chrome and Edge have no problems and no errors when accessing the site. But: Firefox won't populate the root element and shows a weird error. Only after refreshing, Firefox shows the site perfectly.
This is the error and the corresponding code ... it doesn't make sense
TypeError: wi.get(...) is undefined
ts Header.jsx:36
React 7
C scheduler.production.min.js:13
T scheduler.production.min.js:14
813 scheduler.production.min.js:14
Webpack 12
react-dom.production.min.js:189:29
React 9
C scheduler.production.min.js:13
T scheduler.production.min.js:14
(Async: EventHandlerNonNull)
813 scheduler.production.min.js:14
Webpack 12
const availableLanguages = [
{
code: "he",
name: "עברית",
country_code: "il",
dir: "rtl",
},
{
code: "en",
name: "English",
country_code: "gb",
},
{
code: "de",
name: "Deutsch",
^---- The error is showing for this code position! There is no code!
country_code: "de",
},
];
This happens on all three environments, tested from three different systems.
Does anyone know what is happening?
EDIT: Full Header.jsx
import { useState, useRef, useEffect } from "react";
import i18next from "i18next";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import useOutsideClick from "../hooks/useOutsideClick";
import useAuth from "../hooks/useAuth";
import Anchor from "./Anchor";
import "./Header.css";
import claryNextLogo from "../images/ClaryNext2.png";
import cookies from "js-cookie";
import { config } from "../Environment";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { solid } from "@fortawesome/fontawesome-svg-core/import.macro";
import { useContext } from "react";
import { WSContext } from "../App";
import { useEffectOnce } from "../hooks/useEffectOnce";
import { distributionService } from "../services/distributionService";
import MessageBox from "./MessageBox";
import useRetryFetch from "../hooks/useRetryFetch";
const availableLanguages = [
{
code: "he",
name: "עברית",
country_code: "il",
dir: "rtl",
},
{
code: "en",
name: "English",
country_code: "gb",
},
{
code: "de",
name: "Deutsch",
country_code: "de",
},
];
function Header() {
const currentLanguageCode = cookies.get("i18next").split("-")[0] || "en";
const currentLanguage = availableLanguages.find(
(l) => l.code === currentLanguageCode
);
const { auth, setAuth } = useAuth();
const navigate = useNavigate();
const dropdownRef = useRef(null);
const retryFetch = useRetryFetch();
const [showLanguageDropdown, setShowLanguageDropdown] = useState(false);
const [showMessageBox, setShowMessageBox] = useState(false);
const [msgBoxTitle, setMsgBoxTitle] = useState("");
const [msgBoxButtons, setMsgBoxButtons] = useState({});
const [msgBoxInputs, setMsgBoxInputs] = useState([]);
const [msgBoxId, setMsgBoxId] = useState("");
const [msgBoxMoreJSX, setMsgBoxMoreJSX] = useState(null);
const [chatRequestUser, setChatRequestUser] = useState("");
const [chatRequestProcessId, setChatRequestProcessId] = useState("");
const [chatRequestRoomId, setChatRequestRoomId] = useState(0);
const { t } = useTranslation();
const { socket } = useContext(WSContext);
const openMessageBox = (title, id, buttons, inputs, moreJSX) => {
setMsgBoxTitle(title);
setMsgBoxId(id);
setMsgBoxButtons(buttons);
setMsgBoxInputs(inputs);
setMsgBoxMoreJSX(moreJSX);
setShowMessageBox(true);
};
const onButton = async (result) => {
console.log("MessageBox button was clicked");
console.dir(result);
if (result.btnId === "yes") {
// chat was accepted, change to ShowFullLog, join room and notify user
socket.send(
JSON.stringify({
command: "acceptchat",
payload: { email: chatRequestUser, roomId: chatRequestRoomId },
})
);
// collect necessary process log information
let response = await retryFetch(
`${config.API_BASE}/api/processes/${chatRequestProcessId}`
);
let process = await response.json();
let stateToPass = {
processId: chatRequestProcessId,
presName: process.prescriptionName,
presHistoryId: process.fiPrescriptionHistory._id,
autochat: true,
};
if (process.fiExpert?.email === auth.email) {
stateToPass.userEmail = process.fiInitiator?.email;
navigate("/fulllog", { state: stateToPass });
} else {
stateToPass.expertEmail = process.fiExpert?.email;
navigate("/userlog", { state: stateToPass });
}
} else {
// chat was refused, send message to requesting user
socket.send(
JSON.stringify({
command: "refusechat",
payload: {
email: chatRequestUser,
roomId: chatRequestRoomId,
},
})
);
}
};
useEffect(() => {
document.body.dir = currentLanguage?.dir || "ltr";
}, [currentLanguage]);
useEffectOnce(() => {
let messageUnsubscribe = distributionService
.getMessage()
.subscribe((msg) => {
console.log("Header incoming message");
switch (msg.command) {
case "requestchat":
setChatRequestUser(msg.payload.email);
setChatRequestProcessId(msg.payload.processId);
setChatRequestRoomId(msg.payload.roomId);
openMessageBox(
t("msg_chat_requested", {
user: msg.payload.email,
processId: msg.payload.processId,
}),
"requestchat",
[
{ id: "yes", text: t("yes") },
{ id: "no", text: t("no") },
],
[],
""
);
break;
}
});
return () => {
// cleanup subscription
messageUnsubscribe.unsubscribe();
};
}, []);
const login = () => {
navigate("/login");
};
const logout = async () => {
let response = await fetch(config.API_BASE "/logout", {
credentials: "include",
});
if (!response.ok) alert(t("msg_error_logout"));
let result = await response.json();
console.log(result);
setAuth({});
socket.send(
JSON.stringify({
command: "logout",
payload: undefined,
})
);
navigate("/");
};
// const register = () => {
// navigate("/register");
// };
const showPrescriptions = () => {
//navigate("/design");
navigate("/prescriptionlist");
};
const goHome = () => {
navigate("/");
};
const openMenu = () => {
setShowLanguageDropdown(true);
};
const closeMenu = () => {
setShowLanguageDropdown(false);
};
const selectLanguage = (code) => {
i18next.changeLanguage(code);
setShowLanguageDropdown(false);
};
useOutsideClick(dropdownRef, closeMenu);
return (
<>
<div className="header-menu">
<div className="title" onClick={goHome}>
<img src={claryNextLogo} alt="ClaryNext logo" width="90" />
</div>
{!auth?.email ? (
<>
<div className="notonmobile">
<div>
<Anchor
onClick={showPrescriptions}
text={t("example_prescriptions")}
/>
</div>
</div>
<div className="rightflex notonmobile">
<div className="rightMargin">
<span> </span>
</div>
<button onClick={login}>{t("login")}</button>
<span className="leftMargin bigger">
<FontAwesomeIcon
onClick={() => openMenu()}
icon={solid("globe")}
/>
</span>
</div>
</>
) : (
<>
<div className="rightMargin notonmobile">
<Anchor
onClick={showPrescriptions}
text={t("prescriptions_and_processes")}
/>
</div>
<div className="rightflex notonmobile">
<div className="rightMargin">
<Anchor onClick={logout} text={t("logout")} />
</div>
<span className="smaller">{auth.email}</span>
<span className="leftMargin bigger">
<FontAwesomeIcon
onClick={() => openMenu()}
icon={solid("globe")}
/>
</span>
</div>
</>
)}
</div>
{showMessageBox ? (
<MessageBox
onButton={onButton}
buttons={msgBoxButtons}
text={msgBoxTitle}
inputs={msgBoxInputs}
id={msgBoxId}
moreJSX={msgBoxMoreJSX}
onClose={() => setShowMessageBox(false)}
/>
) : (
""
)}
{showLanguageDropdown ? (
<div className="language_dropdown" ref={dropdownRef}>
{availableLanguages.map((lang, idx) => (
<p key={idx} onClick={() => selectLanguage(lang.code)}>
<span
className={`flag-icon flag-icon-${lang.country_code}`}
></span>
{lang.name}
</p>
))}
</div>
) : (
""
)}
</>
);
}
export default Header;
CodePudding user response:
Originally, I had the code to access the cookie in the main function scope. After I moved it into the useEffect[]
callback, it started working also in Firefox.