useImperativeHandle
useImperativeHandle
av Ole Petter den 15. mars 2023
Sist oppdatert: 17 mars, 2023 kl 15:06useImperativeHandle er en React hook som er nyttig i flere tilfeller hvor man vil forhindre unødvendig ekstra rendering av en komponent. I dette eksempelet brukes den til å vise og skjule en modal, og ved hjelp av React.forwardRef kan man lage funksjoner som kan sendes tilbake til en foreldrekomponent.
Foreldrekomponenten kan også sende verdier og funksjoner fra en under-komponent til en annen, så lenge den også bruker forwardRef. React context eller Redux brukes ofte til å håndtere slike situasjoner med state management, men i tilfeller som den under er det gjerne litt i overkant mye arbeid hvis man har en liten applikasjon.
useImperativeHandle(
ref,
() => {
return {
openModal: () => setShow(true),
closeModal: () => onClose(),
isOpen: () => show,
};
},
[]
);
Modalen blir eksportert wrappet med React.forwardRef:
export default forwardRef(Modal);
Bruk av useImperativeHandle gjør at man slipper å sende props frem og tilbake mellom komponenter, og sette opp en egen ekstra useState() funksjon i foreldrekomponenten.
Contents
Kode
App.tsx
import { useRef } from 'react';
import './App.css';
import Modal, { ModalProps } from './components/Modal';
function App() {
const modalRef = useRef<ModalProps>(null);
function openModal() {
modalRef?.current?.openModal();
}
return (
<div className="App">
<h2>useImperativeHandle</h2>
<button onClick={openModal}>Open modal</button>
<Modal ref={modalRef} />
</div>
);
}
export default App;
Modal.tsx
import { forwardRef, useImperativeHandle, useState } from 'react';
export type ModalProps = {
openModal: () => void;
closeModal: () => void;
isOpen: () => boolean;
};
function Modal(props: any, ref: any) {
const [show, setShow] = useState(false);
function onClose() {
return setShow(false);
}
useImperativeHandle(
ref,
() => {
return {
openModal: () => setShow(true),
closeModal: () => onClose(),
isOpen: () => show,
};
},
[]
);
return (
<div>
{show && (
<div
className="modal-background"
style={{
top: 0,
left: 0,
height: '100%',
width: '100%',
position: 'fixed',
backgroundColor: 'rgba(0, 0, 0, 0.4)',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<div
className="modal"
style={{
height: '50%',
width: '50%',
justifyContent: 'center',
backgroundColor: 'white',
}}
>
<h2>Modal</h2>
<button onClick={onClose}>Close</button>
</div>
</div>
)}
</div>
);
}
export default forwardRef(Modal);
https://stackblitz.com/edit/vitejs-vite-3uz6mc?file=src/components/Modal.tsx