как использовать функцию внутри провайдера

#javascript #reactjs #next.js

Вопрос:

У меня есть такой провайдер:

 import {createContext, useContext, useState} from 'react'

// Create Context object.
const CartContext = createContext({
   deliveryPersion:'own',//or other
   coupon:{},
   updateCoupon: (obj) => {},
   updateDeliveryPersion: (type) => {},
})



// Export Provider.
export function CartProvider(props) {

   const updateCoupon = (_coupon) => {
      setState({...state,coupon: _coupon})
   }


  const updateDeliveryPersion = (type) => {
     setState({...state,deliveryPersion: type})
   }



   const initState = {
      deliveryPersion:'own',
      coupon:{},
      updateCoupon:updateCoupon,
      updateDeliveryPersion:updateDeliveryPersion
   }

   const [state, setState] = useState(initState)
    
    return (
       <CartContext.Provider value={state}>
        {props.children}
       </CartContext.Provider>
    )
}

// Export useContext Hook.
export function useCartContext() {
    return useContext(CartContext);
}
 

Мой senario:

внутри component1 я обновил deliveryPersion переменную следующим образом:

 ...
cartContext.updateDeliveryPersion('other')
 

внутри component2 я обновил coupon объект:

 const data = {/**/}
cartContext.updateCoupon(data)
 

при этом здесь deliveryPersion изменено значение по умолчанию.( own значение)

в чем моя проблема?

Ответ №1:

Вы можете передать все, что вам нужно, для повторного использования в вашем CartContext.Например, значение поставщика:

 <CardContext.Provider value={{state, updateCoupon, updateDeliveryPersion}}>
  ... You need to call the components that will use the context here
</CardContext.Provider>
 

затем в ваших дочерних компонентах:

 const { state, updateCoupon, updateDeliveryPersion } = useContext(CardContext);
 

Или просто то, что вам нужно использовать в компоненте. Надеюсь, это может помочь. Вы можете прочитать больше здесь: https://en.reactjs.org/docs/context.html .

Ответ №2:

Вы уже определили свой useCardContext хук, поэтому можете использовать его в своем функциональном компоненте следующим образом:

 // Let say you want to use the updateDeliveryPersion method from your hook
const {updateDeliveryPersion} = useCardContext();
 

Кстати, если вы хотите установить новое состояние с предыдущим значением, вам следует использовать обратный вызов вместо передачи текущего зафиксированного значения состояния:

 const updateCoupon = (_coupon) => {
      setState(prev=>{...prev,coupon: _coupon})
   }
 

Кроме того, вы также можете кэшировать свое значение контекста с useMemo помощью, чтобы избежать дополнительной повторной визуализации дочернего элемента (в данном случае это обычно все ваше приложение).