I’ve developed a website with React where I’m fetching data from a JSON file inside a Context component:
import { createContext, useContext, useState, useEffect } from "react";
const LanguageContext = createContext(undefined)
export const LanguageProvider = ({ children }) => {
const [language, setLanguage] = useState('ES');
const updateLanguage = e => setLanguage(e.target.value)
const [text, setText] = useState({});
useEffect(() => {
fetch(`https://raw.githubusercontent.com/julenclarke/ejtos-react_budget_app/main/languagesdata.json`)
.then((response) => response.json())
.then((jsonData) => setText(jsonData))
.catch((error) => console.log(error));
}, []);
return (
<LanguageContext.Provider
value={{
language,
updateLanguage: updateLanguage,
text
}}
>
{children}
</LanguageContext.Provider>
)
}
export const useLanguage = () => useContext(LanguageContext);
And then I call to that data from another component:
import {Link} from 'react-router-dom';
import MenuItem from '@mui/material/MenuItem';
import FormControl from '@mui/material/FormControl';
import Select from '@mui/material/Select';
import { useLanguage } from './LanguageContext';
function Header() {
const { language, updateLanguage, text } = useLanguage();
return (
<div className="header">
<div className="header-logo">
<Link to="/" className="nav-item">
<img width={300} src={require("../assets/img/julenclarkelogo.png")} alt="Julen Clarke logo" />
</Link>
</div>
<div className="header-links">
{/* <!-- divs in reverse order because of flex-direction: row-reverse; --> */}
<div className="language-picker">
<FormControl variant="standard" sx={{ m: 1, minWidth: 40 }}>
<Select
labelId="demo-simple-select-standard-label"
id="demo-simple-select-standard"
value={language}
onChange={updateLanguage}
label="ES"
>
<MenuItem value={'ES'}>ES</MenuItem>
<MenuItem value={'EU'}>EU</MenuItem>
<MenuItem value={'EN'}>EN</MenuItem>
</Select>
</FormControl>
</div>
<div className="header-nav-list">
<ul>
<li><Link to="/videos" className="nav-item">{text[language].videos}</Link></li>
<li><Link to="/photos" className="nav-item">{text[language].photos}</Link></li>
<li><Link to="/cv" className="nav-item">{text[language].cv}</Link></li>
<li><Link to="/press" className="nav-item">{text[language].press}</Link></li>
<li><Link to="/contact" className="nav-item">{text[language].contact}</Link></li>
</ul>
</div>
</div>
</div>
);
}
export default Header;
Where depending on the value of the language I extract a different piece of data from the JSON file already mentioned:
{
"EU": {
"videos": "Bideoak",
"photos": "Argazkiak"
},
"ES": {
"videos": "Vídeos",
"photos": "Fotos"
},
"EN": {
"videos": "Videos",
"photos": "Photos"
}
}
My problem is that I’m getting the following error when compiling:
ERROR
Cannot read properties of undefined (reading 'videos')
TypeError: Cannot read properties of undefined (reading 'videos')
at Header (http://localhost:3000/static/js/bundle.js:2800:40)
at renderWithHooks (http://localhost:3000/static/js/bundle.js:48914:22)
at mountIndeterminateComponent (http://localhost:3000/static/js/bundle.js:52200:17)
at beginWork (http://localhost:3000/static/js/bundle.js:53496:20)
at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:38506:18)
at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:38550:20)
at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:38607:35)
at beginWork$1 (http://localhost:3000/static/js/bundle.js:58481:11)
at performUnitOfWork (http://localhost:3000/static/js/bundle.js:57728:16)
at workLoopSync (http://localhost:3000/static/js/bundle.js:57651:9)
I don’t know why it says ‘videos’ is undefined because if I make the changes after compiling it kind of works the way I want, so I suspect it might have to do something with the rendering. However, the compilation error description is referring to compilation files to which I’m not familiar at all.