useContext иногда не определен в системе состояний - PullRequest
0 голосов
/ 03 августа 2020

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

  1. ms.dispatch не определено в ModalConfig. js примерно в 50% случаев. То есть иногда отправка будет корректно запускаться из modalA / modalB, но иногда это не так, потому что ms не имеет свойства отправки.
  2. Я получаю сообщение «Ошибка: недопустимый вызов ловушки» при попытке вызвать getModalConfig из функции asyn c, которая читает / пишет из хранилища.

У меня есть другие экраны, использующие аналогичную архитектуру, но без файлов конфигурации - и они работают хорошо, поэтому я подозреваю, что есть некоторые проблема с тем, как я настроил хуки в файлах конфигурации, но я не знаю, как исправить. Я пробовал запоминать ms в ModalConfig. js, но это не помогло.

Пример ниже. В принципе, у меня есть несколько разных типов модальных окон, для которых я получаю конфигурации, и эти конфигурации также должны иметь доступ к глобальному модальному состоянию. Информация о конфигурации передается компоненту ModalContent, который строго обрабатывает представление, поэтому я исключил его из этого примера.

Компоненты <Modal/> и <Screen/> заключены в оболочку. Я запомнил функцию отправки, чтобы решить некоторые проблемы, связанные с повторяющимися вызовами, как рекомендовано в этом сообщении

Заранее благодарим за любую помощь с этим.

Экран. js

export default Screen = () => {
  const ms = useContext(modalStore)

  function showModalType(){
    const modalType = someCondition?'modalA':'modalB'
    ms.dispatch({type:'showModal', modalType:modalType})
  }

  return <Button title='Show Modal' onPress={()=>showModalType()}/>
}

ModalState. js

const initialState = {modalType:null, visible:false}
const modalStore = createContext(initialState)
const { Provider } = modalStore
const StateProvider = ({children) => {
  const memoizedDispatchFunction = useCallback(modalDispatcher,[])
  const [state, dispatch] = useReducer(modalDispatcher,initialState)
  function modalDispatcher(state, payload){
    switch (payload.type){
      case 'showModal':
        return {
          ...state,
          modalType:payload.modalType,
          isVisible:true
        }
      case 'doSomethingModalA':
        console.log('did something with modal A')
        return state
      case 'doSomethingModalB':
        console.log('did something with modal B')
        return state
    }
  }
  return <Provider value={{state:state, dispatch:dispatch}}>{children}</Provider>

}

return { modalStore, StateProvider }

Modal. js

export default Modal = () => {
  const ms = useContext(modalStore)
  const config = getModalConfig({type:ms.state?.modalType})
  return React.createElement(ModalContent, {
      isVisible:ms.state.isVisible, 
      modalType:ms.state.modalType, 
      ...config
  }
}

ModalConfig. js

export function getModalConfig({type}){
  const ms = useContext(modalStore)
  const config = {
    modalA:{
      func:(() => ms.dispatch({type:'doSomethingModalA'})),
      prop:'propval'
    }
    modalB:{
      func:(() => ms.dispatch({type:'doSomethingModalB'})),
      prop:'propval'
    }
  }
   
  return config[type]
}

...