Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
162 views
in Technique[技术] by (71.8m points)

javascript - LocalStorage includes an empty array on every render

I'm trying to update my localStorage with new items that are added to my shopping cart. However, every time an item is added, an empty array is added before it (see screenshot). Why is this?

I'm thinking I need to add a ternary operator to return an empty array if there are no existing items in the cart and to return the current items in the cart if there are items currently in localStorage. Is this correct, or do I have a syntax error?

Screenshot: enter image description here

Code in question:

useEffect(() => {
  const newData = JSON.parse(localStorage.getItem('product')) || [];
  newData.push(cart);
  localStorage.setItem('product', JSON.stringify(newData));
}, [cart])

Full code:

import React, { useState, useEffect } from 'react';
import './../App.css';
import * as ReactBootStrap from 'react-bootstrap';

function Cart(props) {

    const [cart, setCart] = useState([]);
    const [quantity, setQuantity] = useState([]);
    const [loading, setLoading] = useState(false);

  useEffect(async () => {
  fetchItems();
}, [])

const itemId = props.match.params.id;
const itemQuantity = parseInt(props.match.params.qty, 10);
const fetchItems = async () => {
  const data = await fetch('https://fakestoreapi.com/products/' + itemId);
  const items = await data.json();
  setCart(items)
  setQuantity(itemQuantity)
  setLoading(true)
}

function price(qty){
  const newPrice = qty * cart.price;
  return newPrice.toFixed(2)
}

useEffect(() => {
  const newData = JSON.parse(localStorage.getItem('product')) || [];
  newData.push(cart);
  localStorage.setItem('product', JSON.stringify(newData));
}, [cart])

    return (
      <div>
        {loading ? (
          <div className="productStyle">
            <img src={cart.image} className="productImage"></img>
            <p>{cart.title}</p>

            <div className="quantity">
              <button className="btn minus-btn" type="button"
                onClick={quantity > 1 ? () => setQuantity(quantity - 1) : null}>-</button>
              <input type="text" id="quantity" placeholder={quantity}/>
              <button className="btn plus-btn" type="button"
                onClick={() => setQuantity(quantity + 1)}>+</button>
            </div>

            <p>${price(quantity)}</p>



          </div>
        ) : (<ReactBootStrap.Spinner className="spinner" animation="border" />)}
      </div>
    );
}

export default Cart;
question from:https://stackoverflow.com/questions/65927857/localstorage-includes-an-empty-array-on-every-render

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are fetching the initial cart content asynchronously, but are setting product to newData right away, i.e., before cart had any content, which means that newData only contains [].

Perhaps just replace newData.push(cart); with cart.length > 0 && newData.push(cart);? Or rethink your logic. Not sure what you want product to contain.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...