My app works perfectly in local, without errors, but when I try to deploy it on netlify or github pages, when I open it, the page is blank and many errors are displayed in the console.
The error says
TypeError: can't access property "length", e is undefined
where e corresponds to items (which is a state).
If I remove these lines of code, I get another error that always concerns items: the problem this time is with items.some, where items is null again.
Whatever I try to do items always result null. I tried console.log(items) in many component files and in all of them the result is null.
This is the netlify link where you can see the error: https://celadon-otter-917b4e.netlify.app/
Navbar.js, where the error is located:
import { Link } from 'react-router-dom';
import Searchbar from './Searchbar';
import { useContext } from 'react';
import FavoritesContext from '../FavoritesContext';
function Navbar() {
const { items } = useContext(FavoritesContext);
return (
<div className='navbar'>
<Link to={'/'} style={{ textDecoration: 'none' }}>
<div className='logo-container'>
<img src="/foglia.png" alt="logo" className='logo'/>
<h3>just<span>vegetables</span></h3>
</div>
</Link>
<Searchbar />
<Link to={'/favorites/'} style={{ textDecoration: 'none' }}>
<h4 className='favor'>Favorites: <span>{items.length}</span></h4>
</Link>
</div>
)
}
export default Navbar;
FavoriteContext.js:
import React, { createContext, useState, useEffect } from "react";
const FavoritesContext = createContext();
export function FavoritesProvider({ children }) {
const [ items, setItems ] = useState([]);
useEffect(() => {
const recipesFavorites = JSON.parse(localStorage.getItem('favorites-recipes'));
setItems(recipesFavorites);
}, []);
const saveToLocalStorage = (item) => {
localStorage.setItem('favorites-recipes', JSON.stringify(item))
}
const addToFavorites = (title, image, id, favorite) => {
if (!favorite) {
const newFavoriteList = [...items, { title, image, id }]
setItems(newFavoriteList);
saveToLocalStorage(newFavoriteList);
};
};
const removeFromFavorites = (title, image, id, favorite) => {
if (favorite) {
const newFavoriteList = items.filter((fav) => fav.id !== id);
setItems(newFavoriteList);
saveToLocalStorage(newFavoriteList);
};
};
return (
<FavoritesContext.Provider value={{ items, setItems, addToFavorites, removeFromFavorites }}>
{children}
</FavoritesContext.Provider>
)
}
export default FavoritesContext;
Card.js:
import { Link } from 'react-router-dom';
import FavoritesContext from '../FavoritesContext';
function Card({ title, image, id }) {
const { addToFavorites } = useContext(FavoritesContext);
const { removeFromFavorites } = useContext(FavoritesContext);
const { items } = useContext(FavoritesContext);
const checkIsAdd = () => {
if(items.some((val) => val.id === id)) {
return true;
}};
const [favorite, setFavorite] = useState(checkIsAdd);
const isInFavorites = (id) => {
return (
<img src='../cuore-pieno.png' alt="like" className='favorite blue' onClick={() => {removeFromFavorites(title, image, id, favorite); toggle()}}/>
)
}
const toggle = () => {
isInFavorites(id);
setFavorite(!favorite);
}
return (
<div className='card'>
{!favorite ? <img src='../cuore-vuoto.png' alt="like" className='favorite' onClick={() => {addToFavorites(title, image, id, favorite); toggle()}}/> : isInFavorites(id)}
<Link to={'/recipe/' id}>
<img src={image} alt='' className='card-image'/>
<div className='card-info-cnt'>
<p className='card-title'>{title}</p>
</div>
</Link>
</div>
)
}
export default Card;
package.json
{
"name": "projetto-react",
"version": "0.1.0",
"homepage": "https://michela-z.github.io/justVegetables",
"main": "index.js",
"dependencies": {
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^0.27.2",
"lodash": "^4.17.21",
"node-env-webpack-plugin": "^1.1.0",
"process": "^0.11.10",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-icons": "^4.4.0",
"react-router-dom": "^6.3.0",
"react-scripts": "^5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"predeploy": "npm run build",
"deploy": "gh-pages -d dist",
"serve": "webpack-dev-server --mode development --open --hot",
"start": "webpack-dev-server",
"build": "webpack --mode production",
"test": "react-scripts test",
"eject": "react-scripts eject",
"webpack": "webpack",
"webpack-dev-server": "webpack-dev-server",
"dev": "npm run webpack-dev-server -- --env mode=development",
"prod": "npm run webpack -- --env mode=production"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@babel/core": "^7.18.13",
"@babel/preset-env": "^7.18.10",
"@babel/preset-react": "^7.18.6",
"babel-loader": "^8.2.5",
"css-loader": "^6.7.1",
"file-loader": "^6.2.0",
"gh-pages": "^4.0.0",
"html-webpack-plugin": "^5.5.0",
"source-map-loader": "^4.0.0",
"url-loader": "^4.1.1",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.10.0"
}
}
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const port = process.env.PORT || 3000;
module.exports = {
mode: 'development',
entry: {
index: {
import: './src/index.js',
dependOn: 'shared',
},
another: {
import: './src/another-module.js',
dependOn: 'shared',
},
shared: 'lodash',
},
output: {
filename: '[name].bundle.js',
path: path.join(__dirname, '/dist')
},
devtool: 'inline-source-map',
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
}
}
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource'
},
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
}),
new webpack.ProvidePlugin({
process: 'process/browser',
}),
],
devServer: {
host: 'localhost',
port: port,
historyApiFallback: true,
open: true
},
optimization: {
runtimeChunk: 'single',
},
};
I'm new to programming, this is my first react app, I tried everything that was in my ability.
CodePudding user response:
Check if there item present before checking its length {items.length}
you can achieve this by
{item && item.length}
or{items?.length}
this will get rid of the errors displayed in live deploy