Hook khusus dengan generik & inferensi
Tulis hook khusus yang dapat digunakan ulang dengan untuk nilai, hasil, dan kesalahan; manfaatkan inferensi serta batasan untuk API yang aman.
Hook khusus dengan generik & inferensi adalah pelajaran TypeScript Academy gratis di CoddyKit. Ini adalah pelajaran 1 dari 2. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar TypeScript Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus TypeScript Academy mencakup 2 pelajaran total.
Pendahuluan
Tujuan: Bangun hook generik yang terasa alami: hook localStorage bertipe, pemuat asinkron, dan pembantu pola terkontrol atau tidak terkontrol. Anda akan mengandalkan inferensi agar pemanggil jarang perlu memberi anotasi tipe.
- Kembalikan tupel untuk ergonomi seperti React
- Gunakan batasan jika diperlukan
- Jangan gunakan any
useLocalStorage<T>
Kembalikan tupel [value, set] seperti pada useState. Jaga agar T tetap konsisten pada nilai dan penyetelnya.
import { useEffect, useState } from "react"
export function useLocalStorage<T>(key: string, initial: T): [T, (v: T | ((prev: T) => T)) => void] {
const [value, setValue] = useState<T>(() => {
try {
const raw = localStorage.getItem(key)
return raw ? (JSON.parse(raw) as T) : initial
} catch {
return initial
}
})
useEffect(() => {
try { localStorage.setItem(key, JSON.stringify(value)) } catch {}
}, [key, value])
const set = (v: T | ((prev: T) => T)) => {
setValue(prev => (typeof v === "function" ? (v as (p: T) => T)(prev) : v))
}
return [value, set]
}
// Usage
// const [user, setUser] = useLocalStorage("user", { id: 1, name: "Ada" })useAsync<T>
Kembalikan objek dengan nilai, kesalahan, dan pemuatan. Tipe nilai disimpulkan dari janji yang dikembalikan oleh fn.
import { useEffect, useState } from "react"
export function useAsync<T>(fn: () => Promise<T>, deps: unknown[] = []) {
const [value, setValue] = useState<T | null>(null)
const [error, setError] = useState<unknown>(null)
const [loading, setLoading] = useState<boolean>(false)
useEffect(() => {
let cancelled = false
setLoading(true)
fn().then(
(v) => { if (!cancelled) { setValue(v); setError(null) } },
(e) => { if (!cancelled) { setError(e); setValue(null) } }
).finally(() => { if (!cancelled) setLoading(false) })
return () => { cancelled = true }
}, deps)
return { value, error, loading }
}
// Usage
// const { value, error, loading } = useAsync(() => fetch("/api").then(r => r.json()))useControlled<T>
Dukung pola terkontrol dan tidak terkontrol dengan satu pembantu. Tupel tersebut menjaga T tetap selaras.
import { useState } from "react"
type ControlledProps<T> = {
value?: T
defaultValue: T
onChange?: (v: T) => void
}
export function useControlled<T>({ value, defaultValue, onChange }: ControlledProps<T>): [T, (v: T) => void] {
const [inner, setInner] = useState<T>(defaultValue)
const isControlled = value !== undefined
const current = isControlled ? (value as T) : inner
const set = (v: T) => { isControlled ? onChange?.(v) : setInner(v) }
return [current, set]
}
// Usage
// const [v, setV] = useControlled({ value, defaultValue: "", onChange: setValue })Inferensi dan batasan
Utamakan inferensi dari argumen; tambahkan batasan extends hanya jika hook Anda memerlukan bidang tertentu.
// Inference works from the initial value
const [settings, setSettings] = useLocalStorage("settings", { theme: "dark", pageSize: 20 })
// T = { theme: string; pageSize: number }
// Constrain T when needed
interface WithId { id: string }
function useById<T extends WithId>(items: T[], id: string) {
return items.find(x => x.id === id) || null
}
// Usage
const user = useById([{ id: "u1", name: "Ada" }], "u1")Kiat
Kiat:
- Kembalikan tupel agar terasa seperti React dan pengetikannya konsisten.
- Jangan pernah menggunakan
anydalam tanda tangan hook publik. - Terima pembaru
(prev) => nextuntuk transisi status yang praktis.
Pemeriksaan pengetikan hook
Pemeriksaan cepat: Tanda tangan mana yang paling sesuai untuk hook localStorage generik?
Ringkasan
Ringkasan: Anda membangun hook generik yang mengandalkan inferensi, menggunakan batasan hanya jika diperlukan, serta menyediakan hasil berbentuk tupel atau objek yang terasa seperti API React bawaan.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Hook khusus dengan generik & inferensi” gratis?
Ya — teks lengkap “Hook khusus dengan generik & inferensi” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus TypeScript Academy, upgrade ke CoddyKit PRO. Kursus TypeScript Academy mencakup 2 pelajaran total.
Apa yang akan aku pelajari di “Hook khusus dengan generik & inferensi”?
Tulis hook khusus yang dapat digunakan ulang dengan untuk nilai, hasil, dan kesalahan; manfaatkan inferensi serta batasan untuk API yang aman. Kamu berlatih TypeScript Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai TypeScript Academy?
Tidak diperlukan pengalaman sebelumnya. TypeScript Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 2.
Berapa lama pelajaran “Hook khusus dengan generik & inferensi” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran TypeScript Academy ini?
Ya. Setiap pelajaran TypeScript Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Hook khusus dengan generik & inferensi
- Tipe Suspense & batas kesalahan