Įvaldykite TypeScript klaidų ribas, kurdami atsparias programas. Atraskite įvairius klaidų tvarkymo tipinius šablonus, geriausias praktikas ir realaus pasaulio pavyzdžius.
TypeScript klaidų ribos: tipiniai klaidų tvarkymo šablonai tvirtiems programų kūrimams
Programinės įrangos kūrimo pasaulyje netikėtos klaidos yra neišvengiamos. Nuo tinklo trikdžių iki netikėtų duomenų formatų – programos turi būti pasirengusios šias situacijas tvarkyti lengvai. TypeScript su savo galinga tipų sistema siūlo tvirtą pagrindą atsparioms programoms kurti. Šiame straipsnyje gilinamasi į TypeScript klaidų ribų sampratą, nagrinėjami skirtingi klaidų tvarkymo tipiniai šablonai, geriausios praktikos ir realaus pasaulio pavyzdžiai, siekiant suteikti jums žinių, kaip sukurti stabilesnį ir lengviau prižiūrimą kodą.
Klaidų tvarkymo svarbos supratimas
Veiksmingas klaidų tvarkymas yra labai svarbus teigiamai vartotojo patirčiai ir bendrai programos būklei. Kai klaidos lieka netvarkytos, jos gali sukelti:
- Avarijas ir nenuspėjamą elgesį: Neapimtos išimtys gali sustabdyti jūsų kodo vykdymą, sukeldamos avarijas ar nenuspėjamus rezultatus.
- Duomenų praradimą ir sugadinimą: Klaidos duomenų apdorojimo ar saugojimo metu gali lemti duomenų praradimą ar sugadinimą, paveikiant vartotojus ir sistemos vientisumą.
- Saugos pažeidžiamumus: Prastas klaidų tvarkymas gali atskleisti jautrią informaciją arba sudaryti galimybes piktavališkoms atakoms.
- Neigiamą vartotojo patirtį: Vartotojai, susidūrę su neaiškiomis klaidos žinutėmis ar programos gedimais, tikėtina, kad patirs nepatogumų, todėl sumažės pasitikėjimas ir priėmimas.
- Sumažėjusį produktyvumą: Kūrėjai skiria laiką netvarkytų klaidų derinimo ir sprendimo veikloms, trukdydami bendram kūrimo našumui ir lėtindami išleidimo ciklus.
Geras klaidų tvarkymas, priešingai, suteikia:
- Švelnų degradavimą: Programa ir toliau veikia, net jei tam tikra jos dalis susiduria su klaida.
- Informacinę grįžtamąją ryšį: Vartotojai gauna aiškias ir glaustas klaidos žinutes, padedančias jiems suprasti ir išspręsti problemą.
- Duomenų vientisumą: Svarbios operacijos valdomos transakciniu būdu, apsaugant svarbią vartotojo informaciją.
- Pagerintą stabilumą: Programa tampa atsparesnė netikėtiems įvykiams.
- Patobulintą priežiūrą: Lengviau identifikuoti, diagnozuoti ir taisyti problemas, kai jos atsiranda.
Kas yra klaidų ribos TypeScript?
Klaidų ribos yra dizaino šablonas, naudojamas siekiant pagauti JavaScript klaidas tam tikroje komponentų medžio dalyje ir lengvai parodyti atsarginį UI, užuot sugriovus visą programą. Nors pats TypeScript neturi specifinės „klaidų ribos“ funkcijos, tokių ribų kūrimo principai ir metodai lengvai taikomi ir patobulinami dėl TypeScript tipų saugumo.
Pagrindinė idėja yra potencialiai klaidas sukeliančio kodo izoliavimas tam skirtame komponente ar modulyje. Šis komponentas veikia kaip apvyniojimas, stebintis viduje esantį kodą. Jei atsiranda klaida, klaidų ribos komponentas ją „pagauta“, užkirsdamas kelią jos plitimui komponentų medžiu ir potencialiai sugriaudamas programą. Vietoj to, klaidų riba gali parodyti atsarginį UI, užregistruoti klaidą arba bandyti atsigauti po problemos.
Klaidų ribų naudojimo privalumai:
- Izoliacija: Užkerta kelią vienos programos dalies klaidoms paveikti kitas.
- Atsarginis UI: Suteikia vartotojui draugiškesnę patirtį nei visiškai sugedusi programa.
- Klaidų registravimas: Palengvina klaidų informacijos rinkimą derinimo ir stebėjimo reikmėms.
- Patobulinta priežiūra: Supaprastina klaidų tvarkymo logiką ir palengvina kodo atnaujinimą bei priežiūrą.
Tipiniai klaidų tvarkymo šablonai TypeScript
TypeScript tipų sistema yra labai veiksminga, kai derinama su tinkamais klaidų tvarkymo šablonais. Štai keletas bendrų ir veiksmingų šablonų klaidoms jūsų TypeScript programose valdyti:
1. Try-Catch blokai
Pagrindinis JavaScript ir TypeScript klaidų tvarkymo elementas yra `try-catch` blokas. Jis leidžia vykdyti kodą `try` bloke ir pagauti visas išmestus išimtis. Tai yra sinchroninė operacija, ideali klaidoms tvarkyti tiesiogiai funkcijoje.
function fetchData(url: string): Promise<any> {
try {
return fetch(url).then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
});
} catch (error) {
console.error("An error occurred while fetching data:", error);
// Handle the error (e.g., display an error message to the user)
return Promise.reject(error);
}
}
Šiame pavyzdyje `fetchData` funkcija bando gauti duomenis iš nurodyto URL. Jei `fetch` kvietimas nepavyksta (pvz., tinklo klaida, netinkamas URL) arba jei atsakymo statusas nėra tinkamas, išmetama klaida. Tada `catch` blokas tvarko klaidą. Atkreipkite dėmesį į `Promise.reject(error)` naudojimą, kad klaida būtų perduota, todėl kviečiantis kodas taip pat galėtų ją tvarkyti. Tai yra įprasta asinchroninėms operacijoms.
2. Promises ir asinchroninis klaidų tvarkymas
Asinchroninės operacijos yra įprastos JavaScript, ypač kai dirbama su API, duomenų bazių sąveika ir failų I/O. Promises suteikia galingą mechanizmą klaidoms šiuose scenarijuose tvarkyti. `try-catch` blokas yra naudingas, tačiau daugeliu atvejų klaidas tvarkysite `.then()` ir `.catch()` Promise metodais.
function fetchData(url: string): Promise<any> {
return fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.catch(error => {
console.error("An error occurred while fetching data:", error);
// Handle the error (e.g., display an error message to the user)
return Promise.reject(error);
});
}
fetchData('https://api.example.com/data')
.then(data => {
console.log("Data fetched successfully:", data);
})
.catch(error => {
console.error("Failed to fetch data:", error);
// Display a user-friendly error message
});
Šiame pavyzdyje `fetchData` funkcija naudoja Promise asinchroninei `fetch` operacijai tvarkyti. Klaidos pagautomos `.catch()` bloke, leidžiant jums jas tvarkyti konkrečiai asinchroninei operacijai.
3. Klaidos klasės ir pasirinktiniai klaidų tipai
TypeScript leidžia apibrėžti pasirinktines klaidos klases, teikiančias labiau struktūrizuotą ir informatyvesnę klaidų tvarkymo patirtį. Tai puiki praktika kuriant pakartotinai naudojamą ir tipų saugią klaidų tvarkymo logiką. Kuriant pasirinktines klaidos klases, galite:
- Pridėti specifinius klaidos kodus: Atskirti įvairius klaidos tipus.
- Suteikti kontekstą: Saugyti papildomus duomenis, susijusius su klaida.
- Pagerinti skaitomumą ir priežiūrą: Padaryti jūsų klaidų tvarkymo kodą lengviau suprantamą.
class ApiError extends Error {
statusCode: number;
code: string;
constructor(message: string, statusCode: number, code: string) {
super(message);
this.name = 'ApiError';
this.statusCode = statusCode;
this.code = code;
// Assign the prototype explicitly
Object.setPrototypeOf(this, ApiError.prototype);
}
}
async function getUserData(userId: number): Promise<any> {
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) {
let errorMessage = 'Failed to fetch user data';
if (response.status === 404) {
errorMessage = 'User not found';
}
throw new ApiError(errorMessage, response.status, 'USER_NOT_FOUND');
}
return await response.json();
} catch (error: any) {
if (error instanceof ApiError) {
console.error("API Error:", error.message, error.statusCode, error.code);
// Handle specific API error based on the code
if (error.code === 'USER_NOT_FOUND') {
// Show a 'user not found' message
}
} else {
console.error("An unexpected error occurred:", error);
// Handle other errors
}
throw error; // Re-throw or handle the error
}
}
getUserData(123)
.then(userData => console.log("User data:", userData))
.catch(error => console.error("Error retrieving user data:", error));
Šiame pavyzdyje apibrėžiama `ApiError` klasė, paveldinti iš integruotos `Error` klasės. Ji apima `statusCode` ir `code` ypatybes, suteikiant daugiau konteksto. `getUserData` funkcija naudoja šią pasirinktinę klaidos klasę, pagavdama ir tvarkydama specifinius klaidos tipus. `instanceof` operatoriaus naudojimas leidžia saugiai tikrinti tipus ir atlikti specifinį klaidų tvarkymą pagal klaidos tipą.
4. `Result` tipas (funkcinis klaidų tvarkymas)
Funkcinis programavimas dažnai naudoja `Result` tipą (taip pat žinomą kaip `Either` tipas), kad atspindėtų sėkmingą rezultatą arba klaidą. Šis šablonas suteikia švarų ir tipų saugų būdą tvarkyti klaidas. `Result` tipas paprastai turi du variantus: `Ok` (sėkmei) ir `Err` (nesėkmei).
// Define a generic Result type
interface Ok<T> {
type: 'ok';
value: T;
}
interface Err<E> {
type: 'err';
error: E;
}
type Result<T, E> = Ok<T> | Err<E>
function divide(a: number, b: number): Result<number, string> {
if (b === 0) {
return { type: 'err', error: 'Division by zero' };
}
return { type: 'ok', value: a / b };
}
const result1 = divide(10, 2);
const result2 = divide(10, 0);
if (result1.type === 'ok') {
console.log('Result:', result1.value);
} else {
console.error('Error:', result1.error);
}
if (result2.type === 'ok') {
console.log('Result:', result2.value);
} else {
console.error('Error:', result2.error);
}
„divide“ funkcija grąžina arba `Ok` tipo `Result`, kuriame yra padalijimo rezultatas, arba `Err` tipo `Result`, kuriame yra klaidos žinutė. Šis šablonas užtikrina, kad kviečiantis kodas būtų priverstas aiškiai tvarkyti tiek sėkmės, tiek nesėkmės scenarijus, užkertant kelią netvarkytoms klaidoms.
5. Dekoratoriai (pažangiam klaidų tvarkymui – retai tiesiogiai naudojami ribų įgyvendinimui)
Nors tai nėra tiesioginis klaidų ribų šablonas, dekoratoriai gali būti naudojami klaidų tvarkymo logikai taikyti deklaratyviu būdu. Tai gali sumažinti jūsų kodo pakartojimą. Tačiau šis naudojimas yra retesnis nei kiti aukščiau pateikti šablonai pagrindiniam klaidų ribų įgyvendinimui.
function handleError(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = async function (...args: any[]) {
try {
const result = await originalMethod.apply(this, args);
return result;
} catch (error: any) {
console.error(`Error in ${propertyKey}:`, error);
// Handle the error here (e.g., log, display a default value, etc.)
return null; // Or throw a more specific error
}
};
return descriptor;
}
class MyService {
@handleError
async fetchData(url: string): Promise<any> {
// Simulate an error
if (Math.random() < 0.5) {
throw new Error('Simulated network error');
}
const response = await fetch(url);
return await response.json();
}
}
Šiame pavyzdyje apibrėžiamas `@handleError` dekoratorius. Dekoratorius apgaubia originalų metodą, pagavdama visas klaidas ir jas registruodamas. Tai leidžia tvarkyti klaidas, nekeičiant paties originalaus metodo kodo.
Klaidų ribų įgyvendinimas priekinės dalies sistemose (React pavyzdys)
Nors pagrindiniai principai išlieka panašūs, klaidų ribų įgyvendinimas šiek tiek skiriasi priklausomai nuo naudojamos priekinės dalies sistemos. Sutelksime dėmesį į React, populiariausią interaktyvių vartotojo sąsajų kūrimo sistemą.
React klaidų ribos
React teikia specialų mechanizmą klaidų riboms kurti. Klaidų riba yra React komponentas, kuris pagavdžia JavaScript klaidas bet kurioje savo vaikų komponentų medžio dalyje, registruoja tas klaidas ir rodo atsarginį UI, užuot sugriovus visą programą. Klaidų ribos pagauna klaidas rengimo, gyvavimo ciklo metodų ir visų jos vaikų komponentų konstruktorių metu.
Pagrindiniai metodai klaidų ribai sukurti React:
- `static getDerivedStateFromError(error)`: Šis statinis metodas iškviečiamas po to, kai žemesnio lygio komponentas išmeta klaidą. Jis gauna klaidą kaip parametrą ir turėtų grąžinti objektą, kad būtų atnaujinta būsena. Jis naudojamas atnaujinti būseną, pavyzdžiui, nustatant `error` vėliavėlę į `true`, kad būtų paleistas atsarginis UI.
- `componentDidCatch(error, info)`: Šis metodas iškviečiamas po to, kai žemesnio lygio komponentas išmeta klaidą. Jis gauna klaidą ir objektą su informacija apie komponentą, kuris išmetė klaidą. Jis paprastai naudojamas klaidai registruoti. Šis metodas iškviečiamas tik dėl klaidų, kurios įvyksta rengiant jo palikuonis.
import React from 'react';
interface Props {
children: React.ReactNode;
}
interface State {
hasError: boolean;
error: Error | null;
}
class ErrorBoundary extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error: Error) {
// Update state so the next render will show the fallback UI.
return { hasError: true, error: error };
}
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
// You can also log the error to an error reporting service
console.error('Uncaught error:', error, errorInfo);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return (
<div className="error-boundary">
<h2>Something went wrong.</h2>
<p>We're working on fixing it!</p>
<details style={{ whiteSpace: 'pre-wrap' }}>
{this.state.error && this.state.error.stack}
</details>
</div>
);
}
return this.props.children;
}
}
export default ErrorBoundary;
Šis `ErrorBoundary` komponentas apgaubia savo vaikų komponentus. Jei bet kokia klaida išmetama apgaubtuose komponentuose, iškviečiamas `getDerivedStateFromError` metodas, kad būtų atnaujinta būsena, priverčiant komponentą persirenderinti su atsarginiu UI. `componentDidCatch` metodas naudojamas klaidų registravimui. Norėdami naudoti `ErrorBoundary`, tiesiog apgaubtumėte savo programos dalis:
import ErrorBoundary from './ErrorBoundary';
function App() {
return (
<div>
<ErrorBoundary>
<MyComponentThatMightError />
</ErrorBoundary>
<AnotherComponent />
</div>
);
}
Įdėjus `ErrorBoundary` komponentą aplink potencialiai probleminius komponentus, izoliuojami tie komponentai ir suteikiamas atsarginis UI klaidos atveju, užkertant kelią visos programos avarijai.
Klaidų ribos kitose sistemose (konceptualiai)
Nors įgyvendinimo detalės skiriasi, pagrindiniai klaidų ribų principai gali būti taikomi kitoms priekinės dalies sistemoms, tokioms kaip Angular ir Vue.js. Paprastai tai pasiekiama naudojant panašias strategijas:
- Angular: Naudojant komponentų klaidų tvarkymą, pasirinktinius klaidų tvarkytojus ir tarpinius sluoksnius. Apsvarstykite galimybę naudoti Angular `ErrorHandler` klasę ir apgaubti potencialiai probleminius komponentus klaidų tvarkymo logika.
- Vue.js: Naudojant `try...catch` blokus komponentuose arba naudojant globalius klaidų tvarkytojus, užregistruotus per `Vue.config.errorHandler`. Vue taip pat turi komponentų lygio klaidų tvarkymo funkcijų, panašių į React klaidų ribas.
Geriausios praktikos klaidų riboms ir klaidų tvarkymui
Norėdami veiksmingai naudoti klaidų ribas ir tipinius klaidų tvarkymo šablonus, apsvarstykite šias geriausias praktikas:
- Izoliuokite klaidas sukeliančius kodus: Apgaubkite komponentus ar kodo dalis, kurios tikėtina išmes klaidas, klaidų ribomis ar atitinkamomis klaidų tvarkymo konstrukcijomis.
- Suteikite aiškias klaidos žinutes: Sukurkite patogias vartotojui klaidos žinutes, kurios suteikia kontekstą ir nurodymus vartotojui. Venkite neaiškios ar techninės terminijos.
- Veiksmingai registruokite klaidas: Įgyvendinkite patikimą klaidų registravimo sistemą, kad sektumėte klaidas, rinktumėte atitinkamą informaciją (klaidų sekas, vartotojo kontekstą ir kt.) ir palengvintumėte derinimo procesą. Naudokite tokias paslaugas kaip Sentry, Bugsnag ar Rollbar gamybos aplinkoms.
- Įgyvendinkite atsarginius UI: Suteikite prasmingus atsarginius UI, kurie lengvai tvarko klaidas ir neleidžia visai programai suirti. Atsarginis variantas turėtų informuoti vartotoją, kas įvyko, ir, jei tinkama, pasiūlyti veiksmus, kuriuos jie gali atlikti.
- Naudokite pasirinktines klaidos klases: Sukurkite pasirinktines klaidos klases, kad atspindėtumėte skirtingus klaidos tipus ir pridėtumėte papildomą kontekstą bei informaciją, kad klaidų tvarkymas būtų veiksmingesnis.
- Apsvarstykite klaidų ribų sritį: Neapgaubkite visos programos viena klaidų riba, nes tai gali paslėpti pagrindines problemas. Vietoj to, strategiškai įdiekite klaidų ribas aplink komponentus ar programos dalis.
- Testuokite klaidų tvarkymą: Rašykite vienetinius ir integracinius testus, kad įsitikintumėte, jog jūsų klaidų tvarkymo logika veikia tinkamai ir kad atsarginiai UI rodomi teisingai. Testuokite scenarijus, kai gali atsirasti klaidos.
- Stebėkite ir analizuokite klaidas: Reguliariai stebėkite programos klaidų žurnalus, kad nustatytumėte pasikartojančias problemas, sektumėte klaidų tendencijas ir nustatytumėte tobulinimo sritis.
- Siekti duomenų patvirtinimo: Patvirtinkite duomenis, gautus iš išorinių šaltinių, kad išvengtumėte netikėtų klaidų, sukeltų netinkamų duomenų formatų.
- Tinkamai tvarkykite Promises ir asinchronines operacijas: Įsitikinkite, kad tvarkote klaidas, kurios gali atsirasti asinchroninėse operacijose, naudodami `.catch()` blokus ar atitinkamus klaidų tvarkymo mechanizmus.
Realaus pasaulio pavyzdžiai ir tarptautiniai aspektai
Apžvelkime keletą praktinių klaidų ribų ir klaidų tvarkymo tipinių šablonų pritaikymo pavyzdžių realiame pasaulyje, atsižvelgiant į tarptautinimą:
Pavyzdys: El. prekybos programa (duomenų gavimas)
Įsivaizduokite el. prekybos programą, kuri rodo produktų sąrašus. Programa gauna produktų duomenis iš pagrindinio API. Klaidų riba naudojama potencialioms API iškvietimų problemoms spręsti.
interface Product {
id: number;
name: string;
price: number;
currency: string;
// ... other product details
}
class ProductList extends React.Component<{}, { products: Product[] | null; loading: boolean; error: Error | null }> {
state = { products: null, loading: true, error: null };
async componentDidMount() {
try {
const products = await this.fetchProducts();
this.setState({ products, loading: false });
} catch (error: any) {
this.setState({ error, loading: false });
}
}
async fetchProducts(): Promise<Product[]> {
const response = await fetch('/api/products'); // API endpoint
if (!response.ok) {
throw new Error(`Failed to fetch products: ${response.status}`);
}
return await response.json();
}
render() {
const { products, loading, error } = this.state;
if (loading) {
return <div>Loading products...</div>;
}
if (error) {
return (
<div className="error-message">
<p>Sorry, we're having trouble loading the products.</p>
<p>Please try again later.</p>
<p>Error details: {error.message}</p> {/* Log the error message for debugging */}
</div>
);
}
return (
<ul>
{products && products.map(product => (
<li key={product.id}>{product.name} - {product.price} {product.currency}</li>
))}
</ul>
);
}
}
// Error Boundary (React Component)
class ProductListErrorBoundary extends React.Component<{children: React.ReactNode}, {hasError: boolean, error: Error | null}> {
constructor(props: any) {
super(props);
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error: Error) {
// Update state so the next render will show the fallback UI.
return { hasError: true, error: error };
}
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
// You can also log the error to an error reporting service
console.error('Product List Error:', error, errorInfo);
}
render() {
if (this.state.hasError) {
// Render a fallback UI (e.g., error message, retry button)
return (
<div className="product-list-error">
<h2>Oops, something went wrong!</h2>
<p>We are unable to load product information at this time.</p>
<button onClick={() => window.location.reload()} >Retry</button>
</div>
);
}
return this.props.children;
}
}
// Usage
function App() {
return (
<div>
<ProductListErrorBoundary>
<ProductList />
</ProductListErrorBoundary>
</div>
);
}
Šiame pavyzdyje:
- `ProductList` gauna produktų duomenis. Jame tvarkoma pakrovimo būsena, sėkmingi produktų duomenys ir klaidos būsena pačiame komponente.
- `ProductListErrorBoundary` naudojamas apgaubti `ProductList` komponentą, kad būtų galima pagauti klaidas rengimo ir API iškvietimų metu.
- Jei API užklausa nepavyksta, `ProductListErrorBoundary` parodys patogią vartotojui klaidos žinutę, užuot sugriovus UI.
- Klaidos žinutė suteikia „bandyti dar kartą“ parinktį, leidžiančią vartotojui atnaujinti.
- Produktų duomenų `currency` laukas gali būti tinkamai rodomas naudojant tarptautinimo bibliotekas (pvz., Intl JavaScript), kuri teikia valiutos formatavimą pagal vartotojo lokacijos nuostatas.
Pavyzdys: Tarptautinis formos patvirtinimas
Apsvarstykite formą, kurioje renkama vartotojo informacija, įskaitant adreso duomenis. Tinkamas patvirtinimas yra būtinas, ypač kai dirbama su vartotojais iš skirtingų šalių, turinčių skirtingus adreso formatus.
// Assume a simplified address interface
interface Address {
street: string;
city: string;
postalCode: string;
country: string;
}
class AddressForm extends React.Component<{}, { address: Address; errors: { [key: string]: string } }> {
state = {
address: {
street: '',
city: '',
postalCode: '',
country: 'US', // Default country
},
errors: {},
};
handleChange = (event: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
const { name, value } = event.target;
this.setState((prevState) => ({
address: {
...prevState.address,
[name]: value,
},
errors: {
...prevState.errors,
[name]: '', // Clear any previous errors for this field
},
}));
};
handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const { address } = this.state;
const errors = this.validateAddress(address);
if (Object.keys(errors).length > 0) {
this.setState({ errors });
}
else {
// Submit the form (e.g., to an API)
alert('Form submitted!'); // Replace with actual submission logic
}
};
validateAddress = (address: Address) => {
const errors: { [key: string]: string } = {};
// Validation rules based on the selected country
if (!address.street) {
errors.street = 'Street address is required';
}
if (!address.city) {
errors.city = 'City is required';
}
// Example: postal code validation based on the country
switch (address.country) {
case 'US':
if (!/^[0-9]{5}(?:-[0-9]{4})?$/.test(address.postalCode)) {
errors.postalCode = 'Invalid US postal code';
}
break;
case 'CA':
if (!/^[A-Za-z][0-9][A-Za-z][ ]?[0-9][A-Za-z][0-9]$/.test(address.postalCode)) {
errors.postalCode = 'Invalid Canadian postal code';
}
break;
// Add more countries and validation rules
default:
if (!address.postalCode) {
errors.postalCode = 'Postal code is required';
}
break;
}
return errors;
};
render() {
const { address, errors } = this.state;
return (
<form onSubmit={this.handleSubmit}>
<label htmlFor="street">Street:</label>
<input
type="text"
id="street"
name="street"
value={address.street}
onChange={this.handleChange}
/>
{errors.street && <div className="error">{errors.street}</div>}
<label htmlFor="city">City:</label>
<input
type="text"
id="city"
name="city"
value={address.city}
onChange={this.handleChange}
/>
{errors.city && <div className="error">{errors.city}</div>}
<label htmlFor="postalCode">Postal Code:</label>
<input
type="text"
id="postalCode"
name="postalCode"
value={address.postalCode}
onChange={this.handleChange}
/>
{errors.postalCode && <div className="error">{errors.postalCode}</div>}
<label htmlFor="country">Country:</label>
<select
id="country"
name="country"
value={address.country}
onChange={this.handleChange}
>
<option value="US">United States</option>
<option value="CA">Canada</option>
<!-- Add more countries -->
</select>
<button type="submit">Submit</button>
</form>
);
}
}
Šiame pavyzdyje:
- `AddressForm` komponentas valdo formos duomenis ir patvirtinimo logiką.
- `validateAddress` funkcija atlieka patvirtinimus pagal pasirinktą šalį.
- Pritaikomos šalies specifinės pašto kodų patvirtinimo taisyklės (parodyti JAV ir Kanada).
- Programa naudoja `Intl` API lokacijos pataisytam formatavimui. Tai būtų naudojama dinamiškai formatuoti skaičius, datas ir valiutas pagal dabartinę vartotojo lokacijos nuostatas.
- Klaidos žinutės gali būti išverstos, kad būtų užtikrinta geresnė vartotojo patirtis visame pasaulyje.
- Šis požiūris leidžia vartotojams užpildyti formą patogiu būdu, nepriklausomai nuo jų buvimo vietos.
Tarptautinimo geriausios praktikos:
- Naudokite lokalizacijos biblioteką: Tokios bibliotekos kaip i18next, react-intl arba LinguiJS teikia funkcijas tekstų vertimui, datų, skaičių ir valiutų formatavimui pagal vartotojo lokaciją.
- Suteikite lokacijos pasirinkimą: Leiskite vartotojams pasirinkti pageidaujamą kalbą ir regioną. Tai gali būti per išskleidžiamąjį meniu, nustatymus arba automatinį aptikimą pagal naršyklės nustatymus.
- Tvarkykite datos, laiko ir skaičių formatus: Naudokite `Intl` API, kad tinkamai formatuotumėte datas, laikus, skaičius ir valiutas skirtingoms lokacijoms.
- Atsižvelkite į teksto kryptį: Suprojektuokite savo UI, kad palaikytumėte ir iš kairės į dešinę (LTR), ir iš dešinės į kairę (RTL) teksto kryptis. Yra bibliotekų, kurios padeda palaikyti RTL.
- Atsižvelkite į kultūrinius skirtumus: Projektuodami savo UI ir klaidos žinutes, atsižvelkite į kultūrinius normus. Venkite naudoti kalbą ar vaizdinius elementus, kurie gali būti įžeidžiantys ar netinkami tam tikrose kultūrose.
- Testuokite skirtingose lokacijose: Išsamiai testuokite savo programą skirtingose lokacijose, kad įsitikintumėte, jog vertimas ir formatavimas veikia teisingai ir UI yra tinkamai rodomas.
Išvada
TypeScript klaidų ribos ir veiksmingi klaidų tvarkymo tipiniai šablonai yra būtini patikimų ir patogiai vartotojui pritaikytų programų kūrimo komponentai. Įgyvendindami šias praktikas galite užkirsti kelią netikėtoms avarijoms, pagerinti vartotojo patirtį ir supaprastinti derinimo bei priežiūros procesus. Nuo pagrindinių `try-catch` blokų iki sudėtingesnio `Result` tipo ir pasirinktinių klaidos klasių – šie šablonai suteikia jums galimybę kurti tvirtas programas, kurios gali atlaikyti realaus pasaulio iššūkius. Priimdami šiuos metodus, sukursite geresnį TypeScript kodą ir užtikrinsite geresnę patirtį jūsų pasauliniams vartotojams.
Nepamirškite pasirinkti klaidų tvarkymo šablonų, kurie geriausiai atitinka jūsų projekto poreikius ir programos sudėtingumą. Visada sutelkite dėmesį į aiškių, informatyvių klaidos žinučių ir atsarginių UI teikimą, kurie padeda vartotojams naršyti bet kokias galimas problemas. Laikydamiesi šių gairių, galite sukurti programas, kurios yra atsparesnės, lengviau prižiūrimos ir galiausiai – sėkmingesnės pasaulinėje rinkoje.
Apsvarstykite galimybę išbandyti šiuos šablonus ir metodus savo projektuose ir pritaikykite juos pagal specifinius programos reikalavimus. Šis požiūris prisidės prie geresnės kodo kokybės ir teigiamesnės patirties visiems vartotojams.