skip to Main Content

I want to create a global modal component using redux/toolkit and manage it globally. When I click the drop-down menu, I create the message I want to display the modal, and when I click the Ok or Cancel button and background, I try to close it.

There is no problem with the event to open the modal, but to close it, send the following error.
Attached is the contents checked according to the error message.

enter image description here

  1. pacakge.json:

    "react": "^18.2.0",
    "react-copy-to-clipboard": "^5.1.0",
    "react-dom": "^18.2.0",
    
  2. modalSlice.js

    import { createSlice } from '@reduxjs/toolkit'
    
    const initialState = {
      modalContent: '',
      isOpen: false,
    }
    
    export const modalSlice = createSlice({
      name: 'modal',
      initialState,
      reducers: {
        openModal: (state, actions) => {
          const { modalContent } = actions.payload
          const updateState = {
            ...state,
            isOpen: true,
            modalContent,
          }
          return updateState
        },
        closeModal: (state, actions) => {
          console.log(actions)
          const updateState = {
            ...initialState,
          }
          return updateState
        },
      },
    })
    
    export const { openModal, closeModal } = modalSlice.actions
    
    export default modalSlice.reducer
    

    Modal.js

    const Modal = () => {
      const dispatch = useDispatch
      const { modalContent } = useSelector((state) => state.modal)
      const modalHandler = (e) => {
        dispatch(closeModal)
      }
      return (
        <>
          <ModalContainer>
            <ModalBack onClick={modalHandler} />
            <ModalContentWrapper>
              <ModalContent>{modalContent}</ModalContent>
              <ModalBtnWrapper>
                <ModalBtn onClick={modalHandler}>취소</ModalBtn>
                <ModalBtn onClick={modalHandler}>확인</ModalBtn>
              </ModalBtnWrapper>
            </ModalContentWrapper>
          </ModalContainer>
        </>
      )
    }
    
  3. npm ls react

    [email protected] /Users/mary/231014 wedding/mobile/wedding_reception
    ├─┬ @fortawesome/[email protected]
    │ └── [email protected] deduped
    ├─┬ @reduxjs/[email protected]
    │ └── [email protected] deduped
    ├─┬ @testing-library/[email protected]
    │ └── [email protected] deduped
    ├─┬ [email protected]
    │ └── [email protected] deduped
    ├─┬ [email protected]
    │ └── [email protected] deduped
    ├─┬ [email protected]
    │ ├── [email protected] deduped
    │ └─┬ [email protected]
    │   └── [email protected] deduped
    ├─┬ [email protected]
    │ ├─┬ [email protected]
    │ │ └── [email protected] deduped
    │ └── [email protected] deduped
    ├─┬ [email protected]
    │ └── [email protected] deduped
    ├── [email protected]
    └─┬ [email protected]
      └── [email protected] deduped
    

2

Answers


  1. Invalid Hook Call Warning
    You might be breaking the Rules of Hooks.

    it should be written like that

     const dispatch = useDispatch(); 
    
    Login or Signup to reply.
  2. Issue

    At first it seems odd how not calling useDispatch could cause an "invalid hook call" error. In the code you have saved a reference to the useDispatch hook function and named it dispatch, and then later called this function in a nested callback function which is clearly a violations of the Rules of Hooks.

    Only Call Hooks at the Top Level

    Don’t call Hooks inside loops, conditions, or nested functions.
    Instead, always use Hooks at the top level of your React function,
    before any early returns.

    const Modal = () => {
      const dispatch = useDispatch // dispatch is reference to useDispatch function
    
      const { modalContent } = useSelector((state) => state.modal)
    
      const modalHandler = (e) => {
        dispatch(closeModal) // e.g. "useDispatch" invoked here
      }
    
      return (
        ...
      )
    }
    

    Solution

    Invoke the useDispatch function correctly at the top level so the actual dispatch function is callable in a callback function.

    const Modal = () => {
      const dispatch = useDispatch(); // dispatch is reference to dispatch function now
    
      const { modalContent } = useSelector((state) => state.modal);
    
      const modalHandler = (e) => {
        dispatch(closeModal); // e.g. real "dispatch" invoked here
      }
    
      return (
        ...
      )
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search