Reputation: 207
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>
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];
};
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>
}
Upvotes: 1
Views: 1059
Reputation: 207
The majority of the changes are in localStorage.js, first i get the key from Count.js and save it to a var saved that outputs the current count as '{"count":5}'. Next i create a var currentVal (previously named initial) and JSON.parse the passed in saved var. JSON.parse converts the string object back into a regular javascript object. resulting in a value now of {count: 5} (or whatever current count: is). Then if the expected object with a count {count: 5} (currentVal) is returning undefined or null give the key which would be {count: 0} else return currentVal. Key is acting as the defaultValue in this instance, not sure why. Also not sure how reusable this localStorage Hook would really be but it should work with any formats similar to Count.js.
Also note the new input onChange handlers and the new conditional rendering the span'(s) below it.
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>
Upvotes: 1
Reputation: 90
Instead of:
const [orderCount, setOrderCount] = useLocalStorage({count: 0}); // The profile image
you should use:
const [orderCount, setOrderCount] = useLocalStorage("count", 0); // The profile image
Upvotes: 1
Reputation: 2828
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.
Upvotes: 1