#javascript #reactjs #frontend
Вопрос:
я сталкиваюсь с этим странным поведением при попытке обновить родительский компонент с помощью функции set для дочернего элемента с реквизитами этот крючок предназначен для открытия и закрытия модального для редактирования элемента
//PARENT FILE //hook const [isEditModalOpen, setEditModalOpen] = useState(false) //more code... //modal {isEditModalOpen amp;amp; lt;EditExcerciseModal setEditModalOpen={setEditModalOpen} isEditModalOpen={isEditModalOpen} /gt;}
и это дочерний код
//CHILD FILE export const EditExcerciseModal = ({setEditModalOpen, excerciseInfo,fetchExcercisesFromRoutine}) //more code etc etc lt;div className="addExcerciseModalContainer"gt; lt;span onClick={() =gt;{ setEditModalOpen(false) }} className="xModal"gt;Xlt;/spangt;
я проверил, и onClick работает. если я изменю родительское состояние вручную, модальный режим будет работать нормально и закроется.
странный случай, когда он работает, — это когда вместо вызова функции set я создаю функцию с параметром setTimeout без времени, как это:
function closeModal(){ setTimeout(() =gt; { setEditModalOpen(false)}, 0); }
есть какие-нибудь идеи? спасибо за помощь
Ответ №1:
Вам нужно создать разделение забот. Модальный состоит из трех частей
- Модальность своего «Я».
- Содержание модального.
- И контейнер из двух.
Вы должны использовать useState()
хук и вызывать setEditModalOpen
один и тот же содержащий компонент.
Вам нужно убедиться, что вы объявляете и устанавливаете состояние внутри одного и того же компонента.
// children would be the content of the modal const Modal = ({ children, selector, open, setOpen }) =gt; { // we need the useEffect hook so that when we change open to false // the modal component will re-render and the portal will not be created useEffect(() =gt; { setOpen(false); //provide useEffect hook with clean up. return () =gt; setOpen(true); }, [selector]); return open ? createPortal(children, selector) : null; }; export const EditExerciseModal = ({ close }) =gt; { return ( lt;divgt; {/* Instead of creating a handler inside this component we can create it in it's parent element */} lt;span onClick={close}gt;Xlt;/spangt; {/* Content */} lt;/divgt; ); }; export const ModalBtn = () =gt; { const [isEditModalOpen, setEditModalOpen] = useState(false); // this is where it all comes together, // our button element will keep track of the isEditModalOpen variable, // which in turn will update both child elements // when true useEffect hook will re-render Modal Component only now it "will" createPortal() // when our EditExerciseModal alls close it will set change the isEditModalOpen to false // which will be passed to the Modal component which // will then cause the component to re-render and not call createPortal() return ( lt;gt; lt;button onClick={() =gt; setEditModalOpen(true)}gt;EditExerciseModallt;/buttongt; {setEditModalOpen amp;amp; ( lt;Modal open={isEditModalOpen} setOpen={setEditModalOpen} selector={'#portal'}gt; lt;div className='overlay'gt; lt;EditExerciseModal close={() =gt; setEditModalOpen(false)} /gt; lt;/divgt; lt;/Modalgt; )} lt;/gt; ); };
Комментарии:
1. Спасибо, чувак. Я немного изучу порталы react и попробую это. У вас есть представление о том, почему он работает при использовании в режиме ожидания с задержкой 0 мс? я думаю, это связано с асинхронными вещами? или просто жучок?
2. @Ewcom в каком компоненте находится эта функция?