I'm trying to store a number for a counter that initializes as 0 and counts up 1 every time a user uploads a photo. Im getting undefined in Profile console.log orderHook.orderCount. In localStorage i get console.log of {count:0}
Any help is greatly appreciated!
LocalStorage.js:
import { useState, useEffect } from 'react';
function getStorageValue(key, defaultValue) {
// getting stored value
const saved = localStorage.getItem(key);
const initial = JSON.parse(saved); // unexpected character @ line 1 column 1
// const initial = JSON.stringify(saved);
return initial || defaultValue;
}
export const useLocalStorage = (key, defaultValue) => {
const [value, setValue] = useState(() => {
console.log(key)
return getStorageValue(key, defaultValue);
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
};
Count.js: custom hook
import { useLocalStorage } from "../../Utilities/localStorage/localStorage"; // Local storage hook
function useOrderCountHook() {
const [orderCount, setOrderCount] = useLocalStorage({count: 0}); // The profile image
const changeOrderCount = () => {
setOrderCount({ count: orderCount.count 1 })
}
return { orderCount, changeOrderCount };
// return [orderCount, changeOrderCount];
}
export default useOrderCountHook;
Profile.js: using customhook
const orderHook = useOrderCountHook(); // How the photo count hook is called
console.log(typeof (orderHook.orderCount)) // undefined
console.log(orderHook.orderCount) // undefined
const handleUploadChange = e => { // Input onChange
if (e.target.files[0]) {
setImage(e.target.files[0]);
} else { }
return handleCountChange()
};
const handleCountChange = () => { // Function for custom count hook
if (orderHook.orderCount === undefined) {
return
} else {
return orderHook.orderCount
}
}
return (
{
currentUser ?
<input
type="file"
for="Upload Image"
accept="image/*"
name="image"
id="file"
onChange={handleUploadChange}
onClick={handleUploadChange}
style={{ display: "none" }}
/>
: ''
}
<i className="bi bi-camera">
{orderHook.orderCount === undefined ?
<span className="banner-list-font mx-1">0 photos</span>
:
<span className="banner-list-font mx-1">{orderHook.orderCount.count} photos</span>
}
</i>
**UPDATE**
So i managed to get it working but when i signed the user out and signed back in now if i try to upload a photo i get the error Cannot read properties of undefined (reading 'count'). which is the defaultValue prop and that console logs as undefined. I think the problem is that count is being stored as an object ?
localStorage.js:
import { useState, useEffect } from 'react';
// function getStorageValue(key, defaultValue) {
// const saved = localStorage.getItem(key);
// console.log(saved, defaultValue, key)// => null undefined {count:0}
// const initial = JSON.parse(saved);
// console.log(initial)
// // const initial = JSON.stringify(saved);
// // return key || defaultValue;
// return initial || defaultValue;
// }
function getStorageValue(key, defaultValue) {
const saved = localStorage.getItem(key);
console.log(saved, defaultValue, key)// => null undefined {count:0}
if (saved === null) {
return defaultValue;
}
return JSON.parse(saved);
}
export const useLocalStorage = (key, defaultValue) => {
console.log(key, defaultValue)// => {count:0} undefined
const [value, setValue] = useState(() => {
return getStorageValue(key, defaultValue);
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
};
Profile.js:
return (
<input
type="file"
for="Upload Image"
accept="image/*"
name="image"
id="file"
onChange={e => { orderHook.changeOrderCount(e); handleUploadChange(e) }}
onClick={handleUploadChange}
style={{ display: "none" }}
/>
<i className="bi bi-camera"></i>
{orderHook.orderCount === undefined || orderHook.orderCount === null ?
<span className="banner-list-font mx-1">0 photos</span>
:
<span className="banner-list-font mx-1">{orderHook.orderCount.count} photos</span>
}
CodePudding user response:
It looks like the error comes from your getStorageValue
function, here is a fixed implementation:
function getStorageValue(key, defaultValue) {
const saved = localStorage.getItem(key);
if (saved === null) {
return defaultValue;
}
return JSON.parse(saved);
}
I would recommend using a library instead of writing your own implementation of useLocalStorage
.
Check out the useStorage
hook from the react-tidy
library.
Disclaimer I am the author of that library.
CodePudding user response:
Instead of:
const [orderCount, setOrderCount] = useLocalStorage({count: 0}); // The profile image
you should use:
const [orderCount, setOrderCount] = useLocalStorage("count", 0); // The profile image
CodePudding user response:
Well i've been testing this for about 15 minutes and i cant get it to break so i think its working....then again i thought this feature was already working a week ago. Heres what i came up with.
LocalStorage.js:
import { useState, useEffect } from 'react';
function getStorageValue(key, defaultValue) {
const saved = localStorage.getItem(key);
console.log(saved, defaultValue, key)
const initial = JSON.parse(saved); // unexpected character @ line 1 column 1
console.log(initial)
if (initial === null || initial === undefined) {
return key
} else {
return initial
}
}
export const useLocalStorage = (key, defaultValue) => {
console.log(key, defaultValue)
const [value, setValue] = useState(() => {
return getStorageValue(key, defaultValue);
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
};
Count.js:
import { useLocalStorage } from "../../Utilities/localStorage/localStorage"; // Local storage hook
function useOrderCountHook() {
const [orderCount, setOrderCount] = useLocalStorage({count: 0}); // The profile image
const changeOrderCount = () => {
setOrderCount({ count: orderCount.count 1 })
}
return { orderCount, changeOrderCount };
}
export default useOrderCountHook;
Profile.js:
const orderHook = useOrderCountHook(); // Photo count hook
{
currentUser ?
<input
type="file"
for="Upload Image"
accept="image/*"
name="image"
id="file"
onChange={e => { orderHook.changeOrderCount(e); handleUploadChange(e) }}
onClick={handleUploadChange}
style={{ display: "none" }}
/>
: ''
}
<div className="">
<i className="bi bi-camera"></i>
{orderHook.orderCount === undefined || orderHook.orderCount === null ?
<span className="banner-list-font mx-1">0 photos</span>
:
<span className="banner-list-font mx-1">{orderHook.orderCount.count} photos</span>
</div>