在将localStorage设置为初始状态后,反应useState卡住了

时间:2020-06-23 14:11:54

标签: javascript reactjs react-hooks

我正在尝试使用React Hooks创建一个购物车,该购物车保存在本地存储中,并在重新加载浏览器时得到检索。

一切都按照我想要的方式工作,但是重新加载浏览器并检索localStorage-data后,项目状态将不再更新。重新加载前后,购物车对象看起来相同。

我的购物车上下文提供程序如下:

  const { itemList } = useContext(ItemContext)

  const [cart, setCart] = useState(() => {
    const localData =
      localStorage.getItem('cart');
    return localData !== null
      ? JSON.parse(localData)
      : [];
  });

  console.log(cart)

  useEffect(() => {
    localStorage.setItem('cart', JSON.stringify(cart))
  }, [cart] )

  const addItem = id => {
    let addedItem = itemList.find(item => item.id === id)
    let addedItemExists = cart.find(item => item.id === id)
    if (addedItemExists) {
      addedItem.quantity += 1
      setCart([...cart]);
    } else {
      addedItem.quantity = 1
      setCart([...cart, addedItem]);
    }
  };

itemList是一个包含三项的虚拟数据列表)

我也试图通过使用reducer来解决这个问题,但是我得到了相同的结果。

我只使用React和JS几周了,所以如果这是一个noobie问题,我感到抱歉。

5 个答案:

答案 0 :(得分:0)

像这样尝试尝试

const [cart, setCart] = useState([]);

 useEffect(() => {
    const localData =
      localStorage.getItem('cart');
    return localData !== null
      ? JSON.parse(localData)
      : [];
  }, [] )

答案 1 :(得分:0)

尝试以下方法:

ForEach(Array(ButtonsData.enumerated()), id: \.element) { i, Data in
    Button(action: {
      ButtonsData[i].Selected = true
      ButtonsData[i].Colour = .green
    }) {
        Text(Data.Crit)
            .font(.system(size: 30))
    }
    .frame(width: 65, height: 55)
    .background(Data.Colour)
    .cornerRadius(10)
}

或者您可以尝试:

const [cart, setCard] = useState(JSON.parse(localStorage.getItem(localData)))

然后使用:

const [cart, setCard] = useState(JSON.parse(localStorage.getItem(localData) : []))

如果您想在cart && cart.map 上进行映射,则cart将是null

答案 2 :(得分:0)

因此,您最初是在设置购物车。 (在useState中)。尝试在useEffect中进行操作。这只是为了干净的代码。我对if-else部分进行了更改。

  const { itemList } = useContext(ItemContext)

  const [cart, setCart] = useState([]);

  useEffect(() => {
    const localData = localStorage.getItem('cart');
    setCart(localData && localData.length > 0 ? JSON.parse(localData): []);
  }, [])

  useEffect(() => {
    localStorage.setItem('cart', JSON.stringify(cart))
  }, [cart] )

  const addItem = id => {
    let addedItem = itemList.find(item => item.id === id)
    let addedItemExists = cart.find(item => item.id === id)
    if (addedItemExists) {
      addedItem.quantity += 1
      setCart(cart => [...cart]);
    } else {
      addedItem.quantity = 1
      setCart(cart => [...cart, addedItem]);
    }
  };

答案 3 :(得分:0)

您只是在useState内部传递了一个函数,而没有对其进行了调用

只需调用该函数即可。

const { itemList } = useContext(ItemContext);

const initialStateFun = () => {
    const localData = localStorage.getItem("cart");
    return localData !== null ? JSON.parse(localData) : [];
  }
const [cart, setCart] = useState(initialStateFun()); //<--- call the fun

console.log(cart);

...

此外,如果您想变得更简单,则只需使用三元

useState(localStorage.getItem('cart') !== null ? JSON.parse(localData) : []);


答案 4 :(得分:0)

要部分更新状态时,需要使用setState的第一个参数,代表先前的状态

setCart((prev) => ([...prev]));
...
setCart((prev) => ([...prev, addedItems]));

而不是使用其当前值。

现在,在addItemaddedItemExists的情况下,您的true函数看起来有问题,您似乎并没有更新本地状态,而是itemList(您只更新了{ {1}}及其当前值。

也许您应该尝试以下方法:

cart