更新 useContext 中的值時,組件不會重新呈現 (Component not re rendering when value from useContext is updated)


問題描述

更新 useContext 中的值時,組件不會重新呈現 (Component not re rendering when value from useContext is updated)

我正在使用 React 的上下文 api 來存儲項目數組。有一個組件可以通過 useContext() 訪問這個數組並顯示數組的長度。還有另一個組件可以訪問該函數以通過 useContext 更新此數組。將項目添加到數組時,組件不會重新渲染以反映數組的新長度。當我導航到應用程序中的另一個頁面時,組件會重新呈現並反映數組的當前長度。每當上下文中的數組發生變化時,我都需要重新渲染組件。

我嘗試使用 Context.Consumer 而不是 useContext,但是當數組發生變化時它仍然不會重新渲染。

//orderContext.js//

import React, { createContext, useState } from "react"

const OrderContext = createContext({
  addToOrder: () => {},
  products: [],
})

const OrderProvider = ({ children }) => {
  const [products, setProducts] = useState([])

  const addToOrder = (idToAdd, quantityToAdd = 1) => {
    let newProducts = products
    newProducts[newProducts.length] = {
      id: idToAdd,
      quantity: quantityToAdd,
    }
    setProducts(newProducts)
  }

  return (
    <OrderContext.Provider
      value={{
        addToOrder,
        products,
      }}
    >
      {children}
    </OrderContext.Provider>
  )
}

export default OrderContext
export { OrderProvider }
//addToCartButton.js//

import React, { useContext } from "react"
import OrderContext from "../../../context/orderContext"

export default ({ price, productId }) => {
  const { addToOrder } = useContext(OrderContext)

  return (
    <button onClick={() => addToOrder(productId, 1)}>
      <span>${price}</span>
    </button>
  )
}

//cart.js//

import React, { useContext, useState, useEffect } from "react"
import OrderContext from "../../context/orderContext"

export default () => {
  const { products } = useContext(OrderContext)
  return <span>{products.length}</span>
}
//gatsby‑browser.js//

import React from "react"
import { OrderProvider } from "./src/context/orderContext"
export const wrapRootElement = ({ element }) => (
   <OrderProvider>{element}</OrderProvider>
)

我希望購物車組件會在更新數組時顯示數組的新長度,但在我導航到另一個頁面時重新渲染組件之前它保持不變。每次更新上下文中的數組時,我都需要它重新渲染。


參考解法

方法 1:

The issue is likely that you're mutating the array (rather than setting a new array) so React sees the array as the same using shallow equality.

Changing your addOrder method to assign a new array should fix this issue:

const addToOrder = (idToAdd, quantityToAdd = 1) =>
  setProducts([
    ...products,
    {
      id: idToAdd,
      quantity: quantityToAdd
    }
  ]);

Edit context‑arrays

方法 2:

As @skovy said, there are more elegant solutions based on his answer if you want to change the original array.

setProducts(prevState => {
  prevState[0].id = newId
  return [...prevState]
})

方法 3:

<p>@skovy's description helped me understand why my component was not re‑rendering.</p>

In my case I had a provider that held a large dictionary and everytime I updated that dictionary no re‑renders would happen.

ex:

const [var, setVar] = useState({some large dictionary});

...mutate same dictionary
setVar(var) //this would not cause re‑render
setVar({...var}) // this caused a re‑render because it is a new object

I would be weary about doing this on large applications because the re‑renders will cause major performance issues. in my case it is a small two page applet so some wasteful re‑renders are ok for me.

(by Jordan PazskovymutoeCory Lewis)

參考文件

  1. Component not re rendering when value from useContext is updated (CC BY‑SA 2.5/3.0/4.0)

#react-context #gatsby #reactjs






相關問題

在項目中使用 Context API 我以前會在異步操作創建者中使用 Redux? (Using Context API in a project I would have previously used Redux in - async action creators?)

Nextjs 和上下文 API (Nextjs and Context API)

從 redux-saga 函數訪問 React 上下文值 (Access React context value from redux-saga function)

如何在 Django 應用程序中用 react ContextAPI 替換 Redux (How can you replace Redux by the react ContextAPI in a Django App)

從深度嵌套的組件更新狀態而不重新渲染父組件 (Update state from deeply nested component without re-rendering parents)

更新 useContext 中的值時,組件不會重新呈現 (Component not re rendering when value from useContext is updated)

為什麼我無法從反應上下文訪問變量?你能找出錯誤嗎? (Why am I not able to access variable from react context? Can you identify the mistake?)

React Hook useEffect 缺少依賴項(在上下文中定義的函數) (React Hook useEffect has a missing dependency (function defined in context))

React Context 是道具鑽探的解毒劑嗎? (Is React Context an antidote for prop drilling?)

主題提供者問題 (Theme Provider issue)

打字稿反應上下文+類型'{}'沒有調用簽名 (Typescript react context + Type '{}' has no call signatures)

next.js socket.io 使用效果不更新套接字消息 (next.js socket.io useeffect not updating on socket message)







留言討論