Menggunakan Typescript dengan React - A Beginner's Guide

Teman-teman, pada malam akhir pekan kami ingin berbagi dengan Anda publikasi menarik lainnya yang kami ingin bertepatan dengan peluncuran grup baru pada kursus "Pengembang JavaScript" .



Setelah menghabiskan beberapa bulan terakhir mengembangkan aplikasi Bereaksi dan perpustakaan menggunakan Typecript, saya memutuskan untuk membagikan beberapa hal yang saya pelajari selama waktu itu. Dalam panduan ini, saya akan memberi tahu Anda tentang template yang saya gunakan untuk naskah dan Bereaksi dalam 80% kasus.

Haruskah saya mempelajari naskah untuk Bereaksi Pengembangan Aplikasi? Layak, masih layak! Bagi saya sendiri, dalam praktiknya saya menyadari bahwa pengetikan yang ketat mengarah pada penulisan kode yang jauh lebih andal, pengembangan cepat, terutama dalam proyek-proyek besar. Pada awalnya, Anda mungkin akan kecewa, tetapi saat Anda bekerja, Anda akan menemukan bahwa setidaknya template minimal akan sangat membantu.

Dan jika Anda terjebak pada sesuatu, ingatlah bahwa Anda selalu dapat mengetik sesuatu seperti apa pun. Siapa pun teman barumu. Dan sekarang kita akan memberikan contoh secara langsung.

Inti Anda bereaksi komponen dengan naskah


Seperti apa komponen reaksi standar pada naskah? Mari kita bandingkan dengan komponen reaksi dalam javascript.

import React from 'react' import PropTypes from 'prop-types' export function StandardComponent({ children, title = 'Dr.' }) { return ( <div> {title}: {children} </div> ) } StandardComponent.propTypes = { title: PropTypes.string, children: PropTypes.node.isRequired, } 

Dan sekarang versi naskah:

 import * as React from 'react' export interface StandardComponentProps { title?: string children: React.ReactNode } export function StandardComponent({ children, title = 'Dr.', }: StandardComponentProps) { return ( <div> {title}: {children} </div> ) } 

Sangat mirip bukan? Kami mengganti propTypes dengan antarmuka typescript .

Header prop tetap opsional, sementara prop pewaris masih diperlukan. Kami mengekspor antarmuka kami jika ada komponen lain yang perlu tautan ke sana.

Memperluas Atribut HTML Standar


Jika kami ingin agar komponen induk dapat memberikan atribut div diketik tambahan, seperti aria-hidden , style atau className , kami dapat mendefinisikannya di interface atau memperluas antarmuka bawaan. Dalam contoh di bawah ini, kami mengatakan bahwa komponen kami menerima properti div standar apa pun selain header dan turunannya.

 import * as React from 'react' export interface SpreadingExampleProps extends React.HTMLAttributes<HTMLDivElement> { title?: string children: React.ReactNode } export function SpreadingExample({ children, title = 'Dr.', ...other }: SpreadingExampleProps) { return ( <div {...other}> {title}: {children} </div> ) } 

Penanganan acara


Kita dapat mengetikkan event handler untuk memastikan argumen event adalah tipe yang benar. Contoh di bawah ini menunjukkan berbagai cara untuk mencapai tujuan ini:

 export interface EventHandlerProps { onClick: (e: React.MouseEvent) => void } export function EventHandler({ onClick }: EventHandlerProps) { // handle focus events in a separate function function onFocus(e: React.FocusEvent) { console.log('Focused!', e.currentTarget) } return ( <button onClick={onClick} onFocus={onFocus} onKeyDown={e => { // When using an inline function, the appropriate argument signature // is provided for us }} > Click me! </button> ) } 

Tidak yakin argumen tanda tangan mana yang akan digunakan? Di editor, arahkan kursor ke properti yang sesuai dari pengendali acara.

Menggunakan obat generik dengan komponen reaksi


Ini adalah fitur yang lebih canggih, tetapi sangat kuat. Biasanya, Anda menentukan tipe data dalam komponen reaksi dengan atribut spesifik. Misalkan komponen Anda memerlukan objek profile .

 interface ProfileType { name: string image: string age: number | null } interface ProfilesProps { profiles: Array<ProfileType> } function Profiles(props: ProfilesProps) { // render a set of profiles } 

Sekarang mari kita bayangkan bahwa Anda memiliki komponen yang dapat menerima array jenis apa pun. Generik seperti paket surat. Kurir (komponen kami) tidak perlu mengetahui isi paket yang Anda kirim, tetapi pengirim (komponen induk) mengharapkan penerima untuk menerima konten yang ia kirim.

Kami menerapkannya seperti ini:

 interface GenericsExampleProps<T> { children: (item: T) => React.ReactNode items: Array<T> } export function GenericsExample<T>({ items, children, }: GenericsExampleProps<T>) { return ( <div> {items.map(item => { return children(item) })} </div> ) } 

Sebuah contoh yang agak aneh ... namun, itu menunjukkan esensinya. Komponen menerima array elemen jenis apa pun, melewatinya dan memanggil fungsi children - children sebagai fungsi render dengan elemen array. Saat komponen induk kami menyediakan render renderer sebagai pewaris, elemen tersebut akan diketik dengan benar!

Tidak mengerti Ini normal. Saya sendiri belum menemukan obat generik sampai akhir, tetapi Anda sepertinya tidak perlu memahaminya secara menyeluruh. Namun, semakin banyak Anda bekerja dengan typescript , semakin masuk akal.

Mengetik kait


Kait sebagian besar bekerja di luar kotak. Dua pengecualian hanya bisa useRef dan useReducer . Contoh di bawah ini menunjukkan bagaimana kita bisa mengetik referensi.

 import * as React from 'react' interface HooksExampleProps {} export function HooksExample(props: HooksExampleProps) { const [count, setCount] = React.useState(0) const ref = React.useRef<HTMLDivElement | null>(null) // start our timer React.useEffect( () => { const timer = setInterval(() => { setCount(count + 1) }, 1000) return () => clearTimeout(timer) }, [count] ) // measure our element React.useEffect( () => { if (ref.current) { console.log(ref.current.getBoundingClientRect()) } }, [ref] ) return <div ref={ref}>Count: {count}</div> } 

Status kami diketik secara otomatis, tetapi kami mengetik ref secara manual untuk menunjukkan bahwa itu akan null atau mengandung elemen div . Ketika kita mengakses useEffect fungsi useEffect , kita perlu memastikan bahwa itu bukan null .

Mengetik gearbox


Dengan gearbox sedikit lebih rumit, tetapi jika diketik dengan benar, maka ini bagus.

 // Yeah, I don't understand this either. But it gives us nice typing // for our reducer actions. type Action<K, V = void> = V extends void ? { type: K } : { type: K } & V // our search response type interface Response { id: number title: string } // reducer actions. These are what you'll "dispatch" export type ActionType = | Action<'QUERY', { value: string }> | Action<'SEARCH', { value: Array<Response> }> // the form that our reducer state takes interface StateType { searchResponse: Array<Response> query: string } // our default state const initialState: StateType = { searchResponse: [], query: '', } // the actual reducer function reducer(state: StateType, action: ActionType) { switch (action.type) { case 'QUERY': return { ...state, query: action.value, } case 'SEARCH': return { ...state, searchResponse: action.value, } } } interface ReducerExampleProps { query: string } export function ReducerExample({ query }: ReducerExampleProps) { const [state, dispatch] = React.useReducer(reducer, initialState) React.useEffect( () => { if (query) { // emulate async query setTimeout(() => { dispatch({ type: 'SEARCH', value: [{ id: 1, title: 'Hello world' }], }) }, 1000) } }, [query] ) return state.searchResponse.map(response => ( <div key={response.id}>{response.title}</div> )) } 

Menggunakan typeof dan keyof untuk keyof opsi komponen


Misalkan kita memerlukan tombol yang dapat memiliki tampilan yang berbeda, yang masing-masing didefinisikan dalam suatu objek dengan seperangkat kunci dan gaya, misalnya:

 const styles = { primary: { color: 'blue', }, danger: { color: 'red', }, } 

Komponen tombol kami harus menerima properti type , yang bisa
kunci apa saja dari objek styles (misalnya, "primer" atau "bahaya" ). Kita bisa mengetiknya cukup sederhana:

 const styles = { primary: { color: 'blue', }, danger: { color: 'red', }, } // creates a reusable type from the styles object type StylesType = typeof styles // ButtonType = any key in styles export type ButtonType = keyof StylesType interface ButtonProps { type: ButtonType } export function Button({ type = 'primary' }: ButtonProps) { return <button style={styles[type]}>My styled button</button> } 

Contoh-contoh ini akan membantu Anda mencapai 80%. Jika Anda macet, itu sering berharga
lihat saja contoh open source yang ada.

Sancho UI adalah sekumpulan komponen reaksi,
dibangun menggunakan naskah dan emosi.
Cetak biru adalah seperangkat komponen lain
react dibangun di atas typescript .

Nah, sesuai tradisi yang sudah ada, kami menunggu komentar Anda.

Source: https://habr.com/ru/post/id456124/


All Articles