Avastage Reacti Portaalide vÔimsus, et luua ligipÀÀsetavaid ja visuaalselt atraktiivseid modaale ning kohtspikreid, parandades kasutajakogemust ja komponentide struktuuri.
Reacti Portaalid: Modaalide ja Kohtspikrite meisterlik kasutamine parema kasutajakogemuse nimel
TĂ€napĂ€evases veebiarenduses on intuitiivsete ja kaasahaaravate kasutajaliideste loomine esmatĂ€htis. React, populaarne JavaScripti teek kasutajaliideste ehitamiseks, pakub selle saavutamiseks mitmesuguseid tööriistu ja tehnikaid. Ăks selline vĂ”imas tööriist on Reacti Portaalid. See blogipostitus sĂŒveneb Reacti Portaalide maailma, keskendudes nende rakendamisele ligipÀÀsetavate ja visuaalselt atraktiivsete modaalide ning kohtspikrite loomisel.
Mis on Reacti Portaalid?
Reacti Portaalid pakuvad viisi renderdada komponendi lapsi DOM-i sÔlme, mis eksisteerib vÀljaspool vanemkomponendi DOM-i hierarhiat. Lihtsamalt öeldes vÔimaldab see teil vabaneda standardsest Reacti komponendipuu struktuurist ja sisestada elemente otse HTML-struktuuri teise ossa. See on eriti kasulik olukordades, kus peate kontrollima virnastamiskonteksti (stacking context) vÔi positsioneerima elemente vÀljaspool nende vanemkonteineri piire.
TavapÀraselt renderdatakse Reacti komponente DOM-is nende vanemkomponentide lastena. See vÔib mÔnikord pÔhjustada stiili- ja paigutusprobleeme, eriti kui tegemist on elementidega nagu modaalid vÔi kohtspikrid, mis peavad ilmuma muu sisu peale vÔi olema positsioneeritud vaateakna (viewport) suhtes. Reacti Portaalid pakuvad lahendust, vÔimaldades neid elemente renderdada otse DOM-ipuu teise ossa, möödudes neist piirangutest.
Miks kasutada Reacti Portaale?
Mitmed olulised eelised muudavad Reacti Portaalid vÀÀrtuslikuks tööriistaks teie Reacti arendusarsenalis:
- Parem stiliseerimine ja paigutus: Portaalid vĂ”imaldavad teil elemente positsioneerida vĂ€ljaspool nende vanemkonteinerit, ĂŒletades stiiliprobleeme, mis on pĂ”hjustatud
overflow: hidden'ist,z-index'i piirangutest vĂ”i keerulistest paigutuspiirangutest. Kujutage ette modaali, mis peab katma kogu ekraani, isegi kui selle vanemkonteineril onoverflow: hidden. Portaalid vĂ”imaldavad teil renderdada modaali otsebody'sse, möödudes sellest piirangust. - Parem ligipÀÀsetavus: Portaalid on ligipÀÀsetavuse seisukohalt ĂŒliolulised, eriti modaalide puhul. Modaali sisu renderdamine otse
body'sse vĂ”imaldab teil hĂ”lpsasti hallata fookuse lĂ”ksustamist (focus trapping), tagades, et ekraanilugejaid vĂ”i klaviatuurinavigatsiooni kasutavad kasutajad pĂŒsivad modaali sees, kui see on avatud. See on oluline sujuva ja ligipÀÀsetava kasutajakogemuse pakkumiseks. - Puhtam komponentide struktuur: Renderdades modaali vĂ”i kohtspikri sisu vĂ€ljaspool peamist komponendipuud, saate hoida oma komponendistruktuuri puhtamana ja paremini hallatavana. See murede lahusus (separation of concerns) muudab teie koodi lihtsamini loetavaks, mĂ”istetavaks ja hooldatavaks.
- Virnastamiskonteksti probleemide vÀltimine: CSS-i virnastamiskontekste vÔib olla kurikuulsalt keeruline hallata. Portaalid aitavad teil neid probleeme vÀltida, vÔimaldades renderdada elemente otse DOM-i juurelementi, tagades, et need on alati korrektselt positsioneeritud teiste lehel olevate elementide suhtes.
Modaalide implementeerimine Reacti Portaalidega
Modaalid on levinud kasutajaliidese muster, mida kasutatakse olulise teabe kuvamiseks vĂ”i kasutajatelt sisendi kĂŒsimiseks. Uurime, kuidas luua modaali Reacti Portaalide abil.
1. Portaali juurelemendi loomine
Esmalt peate looma DOM-sÔlme, kuhu modaal renderdatakse. Tavaliselt tehakse seda, lisades oma HTML-faili (tavaliselt body'sse) kindla ID-ga div elemendi:
<div id="modal-root"></div>
2. Modaali komponendi loomine
JĂ€rgmiseks looge Reacti komponent, mis esindab modaali. See komponent sisaldab modaali sisu ja loogikat.
import React, { useState, useEffect, useRef } from 'react';
import ReactDOM from 'react-dom';
const Modal = ({ isOpen, onClose, children }) => {
const [mounted, setMounted] = useState(false);
const modalRoot = useRef(document.getElementById('modal-root'));
useEffect(() => {
setMounted(true);
return () => setMounted(false);
}, []);
if (!isOpen) return null;
const modalContent = (
<div className="modal-overlay" onClick={onClose}>
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
{children}
<button onClick={onClose}>Sule</button>
</div>
</div>
);
return mounted && modalRoot.current
? ReactDOM.createPortal(modalContent, modalRoot.current)
: null;
};
export default Modal;
Selgitus:
isOpenprop: MÀÀrab, kas modaal on nĂ€htav.onCloseprop: Funktsioon modaali sulgemiseks.childrenprop: Sisu, mida kuvatakse modaali sees.modalRootref: Viitab DOM-sĂ”lmele, kuhu modaal renderdatakse (#modal-root).useEffecthook: Tagab, et modaal renderdatakse alles pĂ€rast komponendi ĂŒhendamist (mount), et vĂ€ltida probleeme, kus portaali juurelement pole kohe saadaval.ReactDOM.createPortal: See on Reacti Portaalide kasutamise vĂ”ti. See vĂ”tab kaks argumenti: Reacti element, mida renderdada (modalContent) ja DOM-sĂ”lm, kuhu see tuleks renderdada (modalRoot.current).- Taustakihil klĂ”psamine: Sulgeb modaali. Kasutame
e.stopPropagation()modal-contentdiv'il, et vÀltida modaali sees tehtud klÔpsude modaali sulgemist.
3. Modaali komponendi kasutamine
NĂŒĂŒd saate Modal komponenti oma rakenduses kasutada:
import React, { useState } from 'react';
import Modal from './Modal';
const App = () => {
const [isModalOpen, setIsModalOpen] = useState(false);
const openModal = () => setIsModalOpen(true);
const closeModal = () => setIsModalOpen(false);
return (
<div>
<button onClick={openModal}>Ava modaal</button>
<Modal isOpen={isModalOpen} onClose={closeModal}>
<h2>Modaali sisu</h2>
<p>See on modaali sisu.</p>
</Modal>
</div>
);
};
export default App;
See nÀide demonstreerib, kuidas kontrollida modaali nÀhtavust isOpen prop'i ning openModal ja closeModal funktsioonide abil. Sisu <Modal> siltide vahel renderdatakse modaali sisse.
4. Modaali stiliseerimine
Lisage CSS-stiilid modaali positsioneerimiseks ja stiliseerimiseks. Siin on pÔhiline nÀide:
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5); /* PoollÀbipaistev taust */
display: flex;
justify-content: center;
align-items: center;
z-index: 1000; /* Tagab, et see on muu sisu peal */
}
.modal-content {
background-color: white;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
}
CSS-i selgitus:
position: fixed: Tagab, et modaal katab kogu vaateakna, sÔltumata kerimisest.background-color: rgba(0, 0, 0, 0.5): Loob modaali taha poollÀbipaistva taustakihi.display: flex, justify-content: center, align-items: center: Tsentreerib modaali horisontaalselt ja vertikaalselt.z-index: 1000: Tagab, et modaal renderdatakse kÔigi teiste lehel olevate elementide peale.
5. LigipÀÀsetavuse kaalutlused modaalide puhul
LigipÀÀsetavus on modaalide implementeerimisel ĂŒlioluline. Siin on mĂ”ned olulised kaalutlused:
- Fookuse haldamine: Kui modaal avaneb, tuleks fookus automaatselt viia modaali sees olevale elemendile (nt esimesele sisestusvÀljale vÔi sulgemisnupule). Kui modaal sulgub, peaks fookus naasma elemendile, mis modaali avamise kÀivitas. Seda saavutatakse sageli Reacti
useRefhook'i abil, et salvestada eelnevalt fookuses olnud element. - Klaviatuurinavigatsioon: Tagage, et kasutajad saaksid modaalis navigeerida klaviatuuri abil (Tab-klahv). Fookus peaks olema modaali sees lÔksus, takistades kasutajatel sellest kogemata vÀlja tab'ida. Raamatukogud nagu
react-focus-lockvÔivad sellega aidata. - ARIA atribuudid: Kasutage ARIA atribuute, et pakkuda ekraanilugejatele semantilist teavet modaali kohta. NÀiteks kasutage
aria-modal="true"modaali konteineril jaaria-labelvÔiaria-labelledby, et anda modaalile kirjeldav silt. - Sulgemismehhanism: Pakkuge mitu viisi modaali sulgemiseks, nÀiteks sulgemisnupp, taustakihil klÔpsamine vÔi Escape-klahvi vajutamine.
Fookuse haldamise nÀide (kasutades useRef'i):
import React, { useState, useEffect, useRef } from 'react';
import ReactDOM from 'react-dom';
const Modal = ({ isOpen, onClose, children }) => {
const [mounted, setMounted] = useState(false);
const modalRoot = useRef(document.getElementById('modal-root'));
const firstFocusableElement = useRef(null);
const previouslyFocusedElement = useRef(null);
useEffect(() => {
setMounted(true);
if (isOpen) {
previouslyFocusedElement.current = document.activeElement;
if (firstFocusableElement.current) {
firstFocusableElement.current.focus();
}
const handleKeyDown = (event) => {
if (event.key === 'Escape') {
onClose();
}
};
document.addEventListener('keydown', handleKeyDown);
return () => {
document.removeEventListener('keydown', handleKeyDown);
if (previouslyFocusedElement.current) {
previouslyFocusedElement.current.focus();
}
};
}
return () => setMounted(false);
}, [isOpen, onClose]);
if (!isOpen) return null;
const modalContent = (
<div className="modal-overlay" onClick={onClose}>
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
<h2>Modaali sisu</h2>
<p>See on modaali sisu.</p>
<input type="text" ref={firstFocusableElement} /> <!-- Esimene fookustatav element -->
<button onClick={onClose}>Sule</button>
</div>
</div>
);
return mounted && modalRoot.current
? ReactDOM.createPortal(modalContent, modalRoot.current)
: null;
};
export default Modal;
Fookuse haldamise koodi selgitus:
previouslyFocusedElement.current: Salvestab elemendi, mis oli fookuses enne modaali avamist.firstFocusableElement.current: Viitab esimesele fookustatavale elemendile modaali *sees* (selles nÀites tekstisisestus).- Kui modaal avaneb (
isOpenon tÔene):- Hetkel fookuses olev element salvestatakse.
- Fookus viiakse elemendile
firstFocusableElement.current. - Lisatakse sĂŒndmuste kuulaja, et kuulata Escape-klahvi, mis sulgeb modaali.
- Kui modaal sulgub (puhastusfunktsioon):
- Escape-klahvi sĂŒndmuste kuulaja eemaldatakse.
- Fookus tagastatakse elemendile, mis oli eelnevalt fookuses.
Kohtspikrite implementeerimine Reacti Portaalidega
Kohtspikrid on vĂ€ikesed informatiivsed hĂŒpikaknad, mis ilmuvad, kui kasutaja hĂ”ljutab kursorit elemendi kohal. Reacti Portaale saab kasutada kohtspikrite loomiseks, mis on korrektselt positsioneeritud, sĂ”ltumata vanemelemendi stiilist vĂ”i paigutusest.
1. Portaali juurelemendi loomine (kui pole juba loodud)
Kui te pole modaalide jaoks veel portaali juurelementi loonud, lisage oma HTML-faili (tavaliselt body'sse) kindla ID-ga div element:
<div id="tooltip-root"></div>
2. Kohtspikri komponendi loomine
import React, { useState, useEffect, useRef } from 'react';
import ReactDOM from 'react-dom';
const Tooltip = ({ text, children, position = 'top' }) => {
const [isVisible, setIsVisible] = useState(false);
const [positionStyle, setPositionStyle] = useState({});
const [mounted, setMounted] = useState(false);
const tooltipRoot = useRef(document.getElementById('tooltip-root'));
const tooltipRef = useRef(null);
const triggerRef = useRef(null);
useEffect(() => {
setMounted(true);
return () => setMounted(false);
}, []);
const handleMouseEnter = () => {
setIsVisible(true);
updatePosition();
};
const handleMouseLeave = () => {
setIsVisible(false);
};
const updatePosition = () => {
if (!triggerRef.current || !tooltipRef.current) return;
const triggerRect = triggerRef.current.getBoundingClientRect();
const tooltipRect = tooltipRef.current.getBoundingClientRect();
let top = 0;
let left = 0;
switch (position) {
case 'top':
top = triggerRect.top - tooltipRect.height - 5; // 5px vahe
left = triggerRect.left + (triggerRect.width - tooltipRect.width) / 2;
break;
case 'bottom':
top = triggerRect.bottom + 5;
left = triggerRect.left + (triggerRect.width - tooltipRect.width) / 2;
break;
case 'left':
top = triggerRect.top + (triggerRect.height - tooltipRect.height) / 2;
left = triggerRect.left - tooltipRect.width - 5;
break;
case 'right':
top = triggerRect.top + (triggerRect.height - tooltipRect.height) / 2;
left = triggerRect.right + 5;
break;
default:
break;
}
setPositionStyle({
top: `${top}px`,
left: `${left}px`,
});
};
const tooltipContent = isVisible && (
<div className="tooltip" style={positionStyle} ref={tooltipRef}>
{text}
</div>
);
return (
<span
ref={triggerRef}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
{children}
{mounted && tooltipRoot.current ? ReactDOM.createPortal(tooltipContent, tooltipRoot.current) : null}
</span>
);
};
export default Tooltip;
Selgitus:
textprop: Tekst, mida kuvatakse kohtspikris.childrenprop: Element, mis kĂ€ivitab kohtspikri (element, mille kohal kasutaja kursorit hĂ”ljutab).positionprop: Kohtspikri asukoht kĂ€ivitava elemendi suhtes ('top', 'bottom', 'left', 'right'). Vaikimisi 'top'.isVisiblestate: Kontrollib kohtspikri nĂ€htavust.tooltipRootref: Viitab DOM-sĂ”lmele, kuhu kohtspikker renderdatakse (#tooltip-root).tooltipRefref: Viitab kohtspikri elemendile endale, mida kasutatakse selle mÔÔtmete arvutamiseks.triggerRefref: Viitab elemendile, mis kĂ€ivitab kohtspikri (children).handleMouseEnterjahandleMouseLeave: SĂŒndmuste kĂ€sitlejad kĂ€ivitava elemendi kohal hĂ”ljumiseks.updatePosition: Arvutab kohtspikri Ă”ige asukoha, tuginedespositionprop'ile ning kĂ€ivitava ja kohtspikri elementide mÔÔtmetele. See kasutabgetBoundingClientRect(), et saada elementide asukoht ja mÔÔtmed vaateakna suhtes.ReactDOM.createPortal: Renderdab kohtspikri sisutooltipRoot'i.
3. Kohtspikri komponendi kasutamine
import React from 'react';
import Tooltip from './Tooltip';
const App = () => {
return (
<div>
<p>
HÔljutage kursorit selle <Tooltip text="See on kohtspikker!
Mitme reaga."
position="bottom">teksti</Tooltip> kohal, et nÀha kohtspikrit.
</p>
<button>
HÔljutage <Tooltip text="Nupu kohtspikker" position="top">siin</Tooltip> kohtspikri nÀgemiseks.
</button>
</div>
);
};
export default App;
See nÀide nÀitab, kuidas kasutada Tooltip komponenti, et lisada tekstile ja nuppudele kohtspikreid. Saate kohandada kohtspikri teksti ja asukohta, kasutades text ja position prop'e.
4. Kohtspikri stiliseerimine
Lisage CSS-stiilid kohtspikri positsioneerimiseks ja stiliseerimiseks. Siin on pÔhiline nÀide:
.tooltip {
position: absolute;
background-color: rgba(0, 0, 0, 0.8); /* Tume taust */
color: white;
padding: 5px;
border-radius: 3px;
font-size: 12px;
z-index: 1000; /* Tagab, et see on muu sisu peal */
white-space: pre-line; /* Austab reavahetusi text prop'is */
}
CSS-i selgitus:
position: absolute: Positsioneerib kohtspikritooltip-root'i suhtes. Reacti komponendis olevupdatePositionfunktsioon arvutab tĂ€psedtopjaleftvÀÀrtused, et paigutada kohtspikker kĂ€ivitava elemendi lĂ€hedale.background-color: rgba(0, 0, 0, 0.8): Loob kohtspikrile kergelt lĂ€bipaistva tumeda tausta.white-space: pre-line: See on oluline reavahetuste sĂ€ilitamiseks, mida vĂ”ite lisadatextprop'i. Ilma selleta ilmuks kogu kohtspikri tekst ĂŒhel real.
Globaalsed kaalutlused ja parimad praktikad
Arendades Reacti rakendusi globaalsele publikule, arvestage jÀrgmiste parimate tavadega:
- Rahvusvahelistamine (i18n): Kasutage teeki nagu
react-i18nextvÔiFormatJStÔlgete ja lokaliseerimise haldamiseks. See vÔimaldab teil oma rakendust hÔlpsasti kohandada erinevatele keeltele ja piirkondadele. Modaalide ja kohtspikrite puhul veenduge, et tekstisisu on korralikult tÔlgitud. - Paremalt vasakule (RTL) tugi: Keelte puhul, mida loetakse paremalt vasakule (nt araabia, heebrea), veenduge, et teie modaalid ja kohtspikrid kuvatakse korrektselt. VÔimalik, et peate elementide positsioneerimist ja stiili kohandama, et arvestada RTL-paigutustega. CSS-i loogilised omadused (nt
margin-inline-startmargin-left'i asemel) vĂ”ivad olla abiks. - Kultuuriline tundlikkus: Olge modaalide ja kohtspikrite kujundamisel teadlik kultuurilistest erinevustest. VĂ€ltige piltide vĂ”i sĂŒmbolite kasutamist, mis vĂ”ivad teatud kultuurides olla solvavad vĂ”i sobimatud.
- Ajavööndid ja kuupÀevavormingud: Kui teie modaalid vÔi kohtspikrid kuvavad kuupÀevi vÔi aegu, veenduge, et need on vormindatud vastavalt kasutaja lokaadile ja ajavööndile. Teegid nagu
moment.js(kuigi pÀrandvara, on siiski laialt levinud) vÔidate-fnsvÔivad sellega aidata. - LigipÀÀsetavus erinevate vÔimetega inimestele: JÀrgige ligipÀÀsetavuse juhiseid (WCAG), et tagada teie modaalide ja kohtspikrite kasutatavus puuetega inimestele. See hÔlmab alternatiivteksti pakkumist piltidele, piisava vÀrvikontrasti tagamist ja klaviatuurinavigatsiooni toe pakkumist.
KokkuvÔte
Reacti Portaalid on vÔimas tööriist paindlike ja ligipÀÀsetavate kasutajaliideste loomiseks. MÔistes, kuidas neid tÔhusalt kasutada, saate luua modaale ja kohtspikreid, mis parandavad kasutajakogemust ning teie Reacti rakenduste struktuuri ja hooldatavust. Pidage meeles, et mitmekesisele publikule arendades tuleb esikohale seada ligipÀÀsetavus ja globaalsed kaalutlused, tagades, et teie rakendused on kaasavad ja kÔigile kasutatavad.