[英]Can't update parent component state with React UseState
im facing this weird behavior when trying to update the parent component with an set function to the child with props this hook is to open and close the modal to edit an element我在尝试使用带有道具的子组件更新父组件时遇到这种奇怪的行为
//PARENT FILE
//hook
const [isEditModalOpen, setEditModalOpen] = useState(false)
//more code...
//modal
{isEditModalOpen && <EditExcerciseModal setEditModalOpen={setEditModalOpen} isEditModalOpen={isEditModalOpen} />}
and this is the child code这是子代码
//CHILD FILE
export const EditExcerciseModal = ({setEditModalOpen, excerciseInfo,fetchExcercisesFromRoutine})
//more code etc etc
<div className="addExcerciseModalContainer">
<span onClick={() =>{ setEditModalOpen(false) }} className="xModal">X</span>
i checked and the onClick is working.我检查了一下,onClick 工作正常。 if i change the parent state manually the Modal works fine and closes.
如果我手动更改父 state,Modal 工作正常并关闭。
the weird case when it its working is when instead of calling the set function i create a function with a setTimeout without time like this:它工作的奇怪情况是,我没有调用集合 function,而是创建了一个带有 setTimeout 的 function,而没有像这样的时间:
function closeModal(){
setTimeout(() => { setEditModalOpen(false)}, 0);
}
any ideas?有任何想法吗? thanks for the help
谢谢您的帮助
You need to create a separation of concern.您需要创建关注点分离。 A Modal consists of three parts
一个Modal由三部分组成
You should be using the useState()
hook and calling setEditModalOpen
in the same containing component.您应该使用
useState()
挂钩并在同一个包含组件中调用setEditModalOpen
。
You need to make sure that you're declaring and setting state inside the same component.您需要确保在同一组件内声明和设置 state。
// children would be the content of the modal
const Modal = ({ children, selector, open, setOpen }) => {
// 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(() => {
setOpen(false);
//provide useEffect hook with clean up.
return () => setOpen(true);
}, [selector]);
return open ? createPortal(children, selector) : null;
};
export const EditExerciseModal = ({ close }) => {
return (
<div>
{/* Instead of creating a handler inside this component we can create it in it's parent element */}
<span onClick={close}>X</span>
{/* Content */}
</div>
);
};
export const ModalBtn = () => {
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 (
<>
<button onClick={() => setEditModalOpen(true)}>EditExerciseModal</button>
{setEditModalOpen && (
<Modal
open={isEditModalOpen}
setOpen={setEditModalOpen}
selector={'#portal'}>
<div className='overlay'>
<EditExerciseModal close={() => setEditModalOpen(false)} />
</div>
</Modal>
)}
</>
);
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.