Home > database >  React Context Not Updating when clicking open modal button
React Context Not Updating when clicking open modal button

Time:02-04

I am trying to open a modal by updating the state of the component. The component is wrapped in a Context Provider.

Although the button seems to be clicking successfully, the Modal will not open

Here is the code with the container which contains the "Open Modal Button"

import { type FC, useRef } from 'react'
import infomation from '@/assets/icons/infomation.svg'
import { useModal } from '@/providers/ModalProvider'

import styles from './Instructions.module.scss'

const Instructions: FC = () => {
  const card = useRef<HTMLDivElement>(null)
  const { openDemoModal } = useModal()

  const onOpenModalClick = () => {
    openDemoModal()
    console.log(openDemoModal)
  }

  return (
    <section ref={card} className={`card ${styles.card}`}>
      <div className={styles.background} />

<div>OPEN THE MODAL DOWN BELOW</div>

      <button variant="outlined" fullWidth onClick={onOpenModalClick}>
        Open Modal
      </button>
    </section>
  )
}

export default Instructions

Here is the file which contains the Context for the Modal, I have tried setting up the context in INITIAL_STATE and tried updating it using the "onOpenModalClick" function - but it doesn't seem to be able to update the ShowModal.current value below.

import { type FC, type PropsWithChildren, createContext, useContext, useRef } from 'react'

import Modal from '@/components/modal/Modal'

type ContextValue = {
  showModal: boolean
  openDemoModal: () => void
}

const INITIAL_STATE: ContextValue = {
  showModal: false,
  openDemoModal: () => {},
}


export const ModalContext = createContext(INITIAL_STATE)


export const ModalProvider: FC<PropsWithChildren> = ({ children }) => {
  const showModal = useRef(INITIAL_STATE.showModal)

  const openDemoModal = () => {
    showModal.current = true
  }

  console.log(showModal.current)
  return (
    <ModalContext.Provider value={{ showModal: showModal.current, openDemoModal }}>
      {children}
      <Modal show={showModal.current} setShow={(shouldShow: boolean) => (showModal.current = shouldShow)} />
    </ModalContext.Provider>
  )
}

export function useModal() {
  const context = useContext(ModalContext)
  if (!context) {
    throw new Error('useModal must be used within a ModalProvider')
  }
  return context
}

Is there any way to update the onOpenModalClick button to make it change the value of showModal.current in the Provider file?

Sorry if the post is unclear, this is my first Stack Overflow post. Let me know if I need to post anymore of the components.

I tried to add a button to the component which updates the Context, however the state failed to update

CodePudding user response:

The useRef does not trigger a re-render when the value changes. Instead you can use a useState hook. Which would look something like this.

type ContextValue = {
  showModal: boolean;
  openDemoModal: () => void;
};

const INITIAL_STATE: ContextValue = {
  showModal: false,
  openDemoModal: () => console.warn('No ModalProvider'),
};

export const ModalContext = createContext(INITIAL_STATE);

export const ModalProvider: FC<PropsWithChildren> = ({ children }) => {
  const [showModal, setShowModal] = useState(false);

  const openDemoModal = () => {
    setShowModal(true)
  };

  console.log(showModal);
  return (
    <ModalContext.Provider
      value={{ showModal, openDemoModal }}
    >
      {children}
      <Modal
        show={showModal}
        setShow={setShowModal}
      />
    </ModalContext.Provider>
  );
};
  • Related