Atskleiskite React „Render Props“ galią. Sužinokite, kaip šis šablonas skatina kodo pakartotinį naudojimą ir leidžia kurti lanksčias programas tarptautinei auditorijai.
React „Render Props“ šablonas: lanksti komponentų logika pasaulinei auditorijai
Nuolat besikeičiančioje front-end kūrimo srityje, ypač React ekosistemoje, architektūriniai šablonai atlieka lemiamą vaidmenį kuriant mastelį keičiančius, lengvai prižiūrimus ir pakartotinai naudojamus komponentus. Tarp šių šablonų „Render Props“ šablonas išsiskiria kaip galinga technika dalytis kodu ir logika tarp React komponentų. Šio tinklaraščio įrašo tikslas – pateikti išsamų „Render Props“ šablono supratimą, jo privalumus, naudojimo atvejus ir tai, kaip jis prisideda prie tvirtų ir pritaikomų programų kūrimo pasaulinei auditorijai.
Kas yra „Render Props“?
„Render Prop“ yra paprasta technika dalytis kodu tarp React komponentų, naudojant „prop“, kurio reikšmė yra funkcija. Iš esmės, komponentas su „render prop“ priima funkciją, kuri grąžina React elementą, ir iškviečia šią funkciją, kad kažką atvaizduotų. Komponentas tiesiogiai nenusprendžia, ką atvaizduoti; jis deleguoja šį sprendimą „render prop“ funkcijai, suteikdamas jai prieigą prie savo vidinės būsenos ir logikos.
Panagrinėkime šį pagrindinį pavyzdį:
class DataProvider extends React.Component {
constructor(props) {
super(props);
this.state = { data: null };
}
componentDidMount() {
// Simulate fetching data
setTimeout(() => {
this.setState({ data: 'Some data from an API' });
}, 1000);
}
render() {
return this.props.render(this.state.data);
}
}
function MyComponent() {
return (
(
{data ? Data: {data}
: Loading...
}
)}
/>
);
}
Šiame pavyzdyje DataProvider
gauna duomenis ir perduoda juos į render
„prop“ funkciją, kurią pateikia MyComponent
. Tuomet MyComponent
naudoja šiuos duomenis savo turiniui atvaizduoti.
Kodėl naudoti „Render Props“?
„Render Props“ šablonas siūlo keletą pagrindinių privalumų:
- Kodo pakartotinis naudojimas: „Render Props“ leidžia jums inkapsuliuoti ir pakartotinai naudoti logiką keliuose komponentuose. Užuot dubliavę kodą, galite sukurti komponentą, kuris atlieka konkrečią užduotį ir dalijasi savo logika per „render prop“.
- Komponentų kompozicija: „Render Props“ skatina kompoziciją, leisdami jums sujungti skirtingas funkcijas iš kelių komponentų į vieną vartotojo sąsajos elementą.
- Atsakomybių atskyrimas: „Render Props“ padeda atskirti atsakomybes, izoliuojant logiką nuo pateikimo. Komponentas, teikiantis „render prop“, tvarko logiką, o komponentas, naudojantis „render prop“, tvarko atvaizdavimą.
- Lankstumas: „Render Props“ siūlo neprilygstamą lankstumą. Komponento vartotojai kontroliuoja *kaip* duomenys ir logika yra atvaizduojami, todėl komponentas tampa labai pritaikomas įvairiems naudojimo atvejams.
Realaus pasaulio naudojimo atvejai ir tarptautiniai pavyzdžiai
„Render Props“ šablonas yra vertingas įvairiuose scenarijuose. Štai keletas dažniausiai pasitaikančių naudojimo atvejų su pavyzdžiais, kurie atsižvelgia į pasaulinę auditoriją:
1. Pelės sekimas
Įsivaizduokite, kad norite sekti pelės poziciją tinklalapyje. Naudodami „Render Prop“, galite sukurti MouseTracker
komponentą, kuris teikia pelės koordinates savo vaikiniams komponentams.
class MouseTracker extends React.Component {
constructor(props) {
super(props);
this.state = { x: 0, y: 0 };
}
handleMouseMove = event => {
this.setState({ x: event.clientX, y: event.clientY });
};
render() {
return (
{this.props.render(this.state)}
);
}
}
function MyComponent() {
return (
(
The mouse position is ({x}, {y})
)}
/>
);
}
Tai lengvai pritaikoma internacionalizuotoms programoms. Pavyzdžiui, įsivaizduokite piešimo programą, kurią naudoja menininkai Japonijoje. Pelės koordinatės galėtų būti naudojamos teptuko potėpiams valdyti:
(
)}
/>
2. Duomenų gavimas iš API
Duomenų gavimas iš API yra įprasta užduotis interneto svetainių kūrime. „Render Prop“ komponentas gali tvarkyti duomenų gavimo logiką ir pateikti duomenis savo vaikiniams komponentams.
class APIFetcher extends React.Component {
constructor(props) {
super(props);
this.state = { data: null, loading: true, error: null };
}
async componentDidMount() {
try {
const response = await fetch(this.props.url);
const data = await response.json();
this.setState({ data: data, loading: false });
} catch (error) {
this.setState({ error: error, loading: false });
}
}
render() {
return this.props.render(this.state);
}
}
function MyComponent() {
return (
{
if (loading) return Loading...
;
if (error) return Error: {error.message}
;
return {JSON.stringify(data, null, 2)}
;
}}
/>
);
}
Tai ypač naudinga dirbant su lokalizuotais duomenimis. Pavyzdžiui, įsivaizduokite, kad rodote valiutų keitimo kursus vartotojams skirtinguose regionuose:
{
if (loading) return Loading exchange rates...
;
if (error) return Error fetching exchange rates.
;
return (
{Object.entries(data.rates).map(([currency, rate]) => (
- {currency}: {rate}
))}
);
}}
/>
3. Formų tvarkymas
Formos būsenos ir patvirtinimo valdymas gali būti sudėtingas. „Render Prop“ komponentas gali inkapsuliuoti formos logiką ir pateikti formos būseną bei tvarkykles savo vaikiniams komponentams.
class FormHandler extends React.Component {
constructor(props) {
super(props);
this.state = { value: '', error: null };
}
handleChange = event => {
this.setState({ value: event.target.value });
};
handleSubmit = event => {
event.preventDefault();
if (this.state.value.length < 5) {
this.setState({ error: 'Value must be at least 5 characters long.' });
return;
}
this.setState({ error: null });
this.props.onSubmit(this.state.value);
};
render() {
return this.props.render({
value: this.state.value,
handleChange: this.handleChange,
handleSubmit: this.handleSubmit,
error: this.state.error
});
}
}
function MyComponent() {
return (
alert(`Submitted value: ${value}`)}
render={({ value, handleChange, handleSubmit, error }) => (
)}
/>
);
}
Apsvarstykite galimybę pritaikyti formos patvirtinimo taisykles tarptautiniams adresų formatams. Komponentas `FormHandler` gali išlikti bendrinis, o „render prop“ apibrėžia konkrečią patvirtinimo ir vartotojo sąsajos logiką skirtingiems regionams:
sendAddressToServer(address)}
render={({ value, handleChange, handleSubmit, error }) => (
)}
/>
4. Funkcijų vėliavėlės ir A/B testavimas
„Render Props“ taip pat gali būti naudojami funkcijų vėliavėlėms valdyti ir A/B testams atlikti. „Render Prop“ komponentas gali nustatyti, kurią funkcijos versiją atvaizduoti, atsižvelgiant į dabartinį vartotoją ar atsitiktinai sugeneruotą vėliavėlę.
class FeatureFlag extends React.Component {
constructor(props) {
super(props);
this.state = { enabled: Math.random() < this.props.probability };
}
render() {
return this.props.render(this.state.enabled);
}
}
function MyComponent() {
return (
{
if (enabled) {
return New Feature!
;
} else {
return Old Feature
;
}
}}
/>
);
}
Atliekant A/B testavimą pasaulinei auditorijai, svarbu segmentuoti vartotojus pagal kalbą, regioną ar kitus demografinius duomenis. Komponentas `FeatureFlag` gali būti modifikuotas, kad atsižvelgtų į šiuos veiksnius nustatant, kurią funkcijos versiją rodyti:
{
return isEnabled ? : ;
}}
/>
„Render Props“ alternatyvos: aukštesnės eilės komponentai (HOC) ir „Hooks“
Nors „Render Props“ yra galingas šablonas, yra alternatyvių metodų, kuriais galima pasiekti panašių rezultatų. Dvi populiarios alternatyvos yra aukštesnės eilės komponentai (HOC) ir „Hooks“.
Aukštesnės eilės komponentai (HOC)
Aukštesnės eilės komponentas (HOC) yra funkcija, kuri priima komponentą kaip argumentą ir grąžina naują, patobulintą komponentą. HOC dažniausiai naudojami norint pridėti funkcionalumą ar logiką esamiems komponentams.
Pavyzdžiui, withMouse
HOC galėtų suteikti pelės sekimo funkcionalumą komponentui:
function withMouse(WrappedComponent) {
return class extends React.Component {
constructor(props) {
super(props);
this.state = { x: 0, y: 0 };
}
handleMouseMove = event => {
this.setState({ x: event.clientX, y: event.clientY });
};
render() {
return (
);
}
};
}
function MyComponent(props) {
return (
The mouse position is ({props.mouse.x}, {props.mouse.y})
);
}
const EnhancedComponent = withMouse(MyComponent);
Nors HOC siūlo kodo pakartotinį naudojimą, jie gali sukelti „prop“ pavadinimų susidūrimus ir apsunkinti komponentų kompoziciją – reiškinys, žinomas kaip „apvalkalų pragaras“ („wrapper hell“).
„Hooks“
React „Hooks“, pristatyti React 16.8 versijoje, suteikia tiesesnį ir išraiškingesnį būdą pakartotinai naudoti būseną turinčią logiką tarp komponentų. „Hooks“ leidžia jums „prisijungti“ prie React būsenos ir gyvavimo ciklo funkcijų iš funkcinių komponentų.
Naudojant useMousePosition
„hook“, pelės sekimo funkcionalumą galima įgyvendinti taip:
import { useState, useEffect } from 'react';
function useMousePosition() {
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
useEffect(() => {
function handleMouseMove(event) {
setMousePosition({ x: event.clientX, y: event.clientY });
}
window.addEventListener('mousemove', handleMouseMove);
return () => {
window.removeEventListener('mousemove', handleMouseMove);
};
}, []);
return mousePosition;
}
function MyComponent() {
const mousePosition = useMousePosition();
return (
The mouse position is ({mousePosition.x}, {mousePosition.y})
);
}
„Hooks“ siūlo švaresnį ir glaustesnį būdą pakartotinai naudoti būseną turinčią logiką, palyginti su „Render Props“ ir HOC. Jie taip pat skatina geresnį kodo skaitomumą ir priežiūrą.
„Render Props“ vs. „Hooks“: tinkamo įrankio pasirinkimas
Sprendimas tarp „Render Props“ ir „Hooks“ priklauso nuo konkrečių jūsų projekto reikalavimų ir asmeninių pageidavimų. Štai jų pagrindinių skirtumų santrauka:
- Skaitomumas: „Hooks“ paprastai lemia skaitomesnį ir glaustesnį kodą.
- Kompozicija: „Hooks“ palengvina komponentų kompoziciją ir padeda išvengti su HOC susijusios „apvalkalų pragaro“ problemos.
- Paprastumas: „Hooks“ gali būti paprasčiau suprasti ir naudoti, ypač kūrėjams, kurie yra naujokai React srityje.
- Senas kodas: „Render Props“ gali būti tinkamesni senesnių kodų bazių priežiūrai arba dirbant su komponentais, kurie nebuvo atnaujinti, kad naudotų „Hooks“.
- Kontrolė: „Render Props“ siūlo aiškesnę atvaizdavimo proceso kontrolę. Galite tiksliai nuspręsti, ką atvaizduoti, remdamiesi „Render Prop“ komponento pateiktais duomenimis.
Geriausios „Render Props“ naudojimo praktikos
Norėdami efektyviai naudoti „Render Props“ šabloną, atsižvelkite į šias geriausias praktikas:
- „Render prop“ funkcija turi būti paprasta: „render prop“ funkcija turėtų sutelkti dėmesį į vartotojo sąsajos atvaizdavimą remiantis pateiktais duomenimis ir vengti sudėtingos logikos.
- Naudokite aprašomuosius „prop“ pavadinimus: Pasirinkite aprašomuosius „prop“ pavadinimus (pvz.,
render
,children
,component
), kad aiškiai nurodytumėte „prop“ paskirtį. - Venkite nereikalingų pervaizdavimų: Optimizuokite „Render Prop“ komponentą, kad išvengtumėte nereikalingų pervaizdavimų, ypač dirbant su dažnai besikeičiančiais duomenimis. Naudokite
React.memo
arbashouldComponentUpdate
, kad išvengtumėte pervaizdavimų, kai „props“ nepasikeitė. - Dokumentuokite savo komponentus: Aiškiai dokumentuokite „Render Prop“ komponento paskirtį ir kaip jį naudoti, įskaitant laukiamus duomenis ir galimus „props“.
Išvada
„Render Props“ šablonas yra vertinga technika kuriant lanksčius ir pakartotinai naudojamus React komponentus. Inkapsuliuodami logiką ir pateikdami ją komponentams per „render prop“, galite skatinti kodo pakartotinį naudojimą, komponentų kompoziciją ir atsakomybių atskyrimą. Nors „Hooks“ siūlo modernesnę ir dažnai paprastesnę alternatyvą, „Render Props“ išlieka galingu įrankiu React kūrėjo arsenale, ypač dirbant su senu kodu arba scenarijuose, reikalaujančiuose smulkmeniškos atvaizdavimo proceso kontrolės.
Suprasdami „Render Props“ šablono privalumus ir geriausias praktikas, galite kurti tvirtas ir pritaikomas programas, kurios tenkina įvairialypę pasaulinę auditoriją, užtikrinant nuoseklią ir įtraukiančią vartotojo patirtį skirtinguose regionuose ir kultūrose. Svarbiausia yra pasirinkti tinkamą šabloną – „Render Props“, HOC ar „Hooks“ – atsižvelgiant į konkrečius jūsų projekto poreikius ir jūsų komandos patirtį. Priimdami architektūrinius sprendimus, visada teikite pirmenybę kodo skaitomumui, priežiūrai ir našumui.