ბიბლიოთეკა
00/07 · ~32 წთ
GUIDEDECK · მდგომარეობა იქ, სადაც მას ადგილი აქვს

მდგომარეობის
მართვა გამოცნობის
გარეშე.

32-წუთიანი სამუშაო სესია კითხვაზე, რომელიც ჩუმად წყვეტს თქვენი აპლიკაციის არქიტექტურას: სად ცხოვრობს მდგომარეობის თითოეული ნაწილი? React-ის ჩაშენებული საშუალებებიდან გლობალურ სთორებამდე და სერვერის მდგომარეობის ქეშებამდე — და პატიოსანი კომპრომისები მათ შორის.

~32 წთდამწყები → საშუალოReact-ზე, იდეები გადადის
გადაახვიეთ
01 · რა ითვლება მდგომარეობად 4 წთ

გაყოფა, რომელიც ყველაფერს წყვეტს:
კლიენტის vs სერვერის მდგომარეობა.

სანამ რომელიმე ბიბლიოთეკას მიმართავთ, თითოეულ მნიშვნელობას ერთი კითხვა დაუსვით: თქვენ ფლობთ მას, თუ ეს სერვერზე მცხოვრები რაღაცის ასლია? მდგომარეობის მართვის თითქმის ყველა შეცდომა ამ ორის აღრევიდან იბადება — და „Redux გვჭირდება“ ტიპის საუბრების უმეტესობა ქრება, როგორც კი მათ გამიჯნავთ.

მდგომარეობა — ნებისმიერი მნიშვნელობა, რომელიც დროთა განმავლობაში იცვლება და რომელსაც თქვენი UI კითხულობს. რთული მისი შენახვა არ არის; რთულია გადაწყვეტა, ვინ ფლობს მას, ვის შეუძლია მისი შეცვლა და ვინ უნდა მოახდინოს რეაქცია, როცა ის იცვლება. ეს სამი სწორად გადაწყვიტეთ და ინსტრუმენტი თითქმის თავად შეირჩევა.

ორი სახე, გვერდიგვერდ

  • კლიენტის მდგომარეობა — იბადება და იმართება ბრაუზერში. გახსნილი მოდალი, აქტიური ტაბი, ვიზარდის ნაბიჯი, ფორმის დრაფტი, თემა. ის სინქრონულია — დააყენებთ და უკვე იქ არის.
  • სერვერის მდგომარეობა — რეალური მნიშვნელობა API-ს უკან, მონაცემთა ბაზაში ცხოვრობს; თქვენი აპლიკაცია ქეშირებულ ასლს ინახავს. მომხმარებლის შეკვეთები, პროდუქტების სია, ძებნის შედეგები. ის ასინქრონულია, საზიაროა მომხმარებლებს შორის და შეიძლება დაძველდეს იმ წამსვე, როცა წამოიღებთ.
  • ამათ განსხვავებული ინსტრუმენტები სჭირდებათ. სერვერის მონაცემების კლიენტის სთორში შენახვა მთელ ამ თემაში ყველაზე გავრცელებული და ყველაზე ძვირი შეცდომაა.
კლიენტის
თქვენ ფლობთ · სინქრონული
სერვერის
ასლი ქეშში · ასინქრონული
მოდალი: ღია / დახურული
პროფილი, შეკვეთები
აქტიური ტაბი, დრაფტი
პროდუქტების სია, ძებნა
თემა, ვიზარდის ნაბიჯი
დაძველდება · საზიარო

ერთი და იგივე სიტყვა, ორი სხვადასხვა პრობლემა. კლიენტის მდგომარეობა თქვენია და მყისიერი; სერვერის მდგომარეობა ნასესხები ასლია, რომელიც ახალი უნდა შეინარჩუნოთ.

სერვერის მონაცემები ლოკალურად
function Profile() { const [user, setUser] = useState(null) // a server copy in useState useEffect(() => { fetch('/api/me').then(r => r.json()).then(setUser) }, []) // no cache, no retry, no dedupe, no refresh } // every screen refetches; the copy silently goes stale
როგორც ქეში (ნაწილი 4)
function Profile() { const { data: user } = useQuery({ queryKey: ['me'], queryFn: () => fetch('/api/me').then(r => r.json()), }) // caching, dedupe, retry, refetch — for free } // one cache, shared everywhere, kept fresh for you

თითქმის ყველაფერი აქ ერთ გაკვეთილზე დადის: შეწყვიტეთ ქეშის ხელით აწყობა useState + useEffect-ისგან და შეწყვიტეთ თქვენივე UI-ის მდგომარეობის სერვერზე განთავსება.

02 · React-ის ჩაშენებული 5 წთ

დაიწყეთ იმით, რაც უკვე გაქვთ:
useState, useReducer, Context.

აპლიკაციების უმეტესობას გაცილებით ნაკლები გლობალური მდგომარეობა სჭირდება, ვიდრე ჰგონია. ბიბლიოთეკას მაშინ მიმართეთ, როცა ამ სამს ნამდვილად აღარ ეყოფა ადგილი. თავად ჰუკების მექანიკისთვის იხილეთ Modern React — აქ ყურადღებას ვამახვილებთ იმაზე, თითოეული სად ჯდება.

useState

ერთი მნიშვნელობა, ერთი კომპონენტი

ნაგულისხმევი არჩევანი. მდგომარეობა, რომელსაც ერთი კომპონენტი ფლობს (და შესაძლოა ერთი-ორი დონით ქვემოთ გადასცემს). როცა ორი განახლება წინა მნიშვნელობაზეა დამოკიდებული, ფუნქციური ფორმა გამოიყენეთ.

const [count, setCount] = useState(0) setCount(c => c + 1) // safe under batching
useReducer

ბევრი გადასვლა, ერთი ადგილი

როცა რამდენიმე ქმედება დაკავშირებულ მდგომარეობას სტრუქტურირებულად ცვლის, რედიუსერი ლოგიკას ერთ ტესტირებად ფუნქციაში კრებს, ხუთი მიმოფანტული setState გამოძახების ნაცვლად.

function reducer(s, a) { switch (a.type) { case 'inc': return { n: s.n + 1 } case 'reset': return { n: 0 } } }
Context

თავი აარიდეთ prop-drilling-ს

Context არ არის მდგომარეობის მენეჯერი — ის ტრანსპორტია. ის მნიშვნელობას ხეში ქვემოთ ატარებს ისე, რომ props ყოველ შრეზე არ გაატაროთ. ის არაფერს ქეშირებს და შერჩევით განახლებებს არ აკეთებს.

const Theme = createContext('light') // provide high, read deep const theme = useContext(Theme)

Context-ის ხელახალი რენდერის ხაფანგი

context-ის მნიშვნელობის ნებისმიერი ცვლილება ხელახლა არენდერებს ყველა consumer-ს — მათაც კი, ვინც მხოლოდ არარელევანტურ ველს კითხულობს. Context-ს ჩაშენებული სელექტორები არ აქვს.

ორი რამ აკბენინებს Context-ს. პირველი — სწრაფად ცვალებადი მნიშვნელობის (მაუსის პოზიცია, მზარდი სია) ერთ კონტექსტში მოთავსება ნელა ცვალებადებთან ერთად. მეორე — მნიშვნელობად ყოველ რენდერზე ახალი ობიექტის გადაცემა: ახალი იდენტობა ყოველთვის ცვლილებად ითვლება.

  • დაიმახსოვრეთ მნიშვნელობა, რომ მისი იდენტობა რენდერებს შორის სტაბილური იყოს.
  • დაყავით კონტექსტები: ერთი იშვიათად ცვალებადი მონაცემებისთვის, მეორე — მოუსვენარისთვის.
  • როცა შერჩევითი გამოწერები დაგჭირდებათ, ეს იმის სიგნალია, რომ ნამდვილ სთორს მიმართოთ (ნაწილი 3).
ახალი ობიექტი ყოველ ჯერზე
// fresh value identity each render → all consumers re-render <AppCtx.Provider value={{ user, theme, setTheme }}> {children} </AppCtx.Provider>
სტაბილური იდენტობა, გაყოფა
const value = useMemo( () => ({ user, theme, setTheme }), [user, theme], // identity changes only when these do ) <AppCtx.Provider value={value}>{children}</AppCtx.Provider>
03 · გლობალური სთორები 5 წთ

როცა კლიენტის მდგომარეობა ფართოდ უნდა გაზიარდეს —
სთორი სელექტორებით.

გლობალური სთორები ორ პრობლემას წყვეტს, რომელსაც Context ვერ ახერხებს: ისინი კომპონენტების ხის გარეთ ცხოვრობენ და კომპონენტები ერთ ნაჭერს ეწერებიან — ამიტომ ცვლილება ხელახლა მხოლოდ იმ კომპონენტებს არენდერებს, რომლებიც ამ ნაჭერს კითხულობენ. სწორედ ეს სელექტორული მოდელია მათი გამოყენების ნამდვილი მიზეზი.

სთორი არის React-ის გარეთ მცხოვრები მდგომარეობა, რომელსაც ისე ეწერებით, რომ მხოლოდ თქვენთვის საინტერესო ნაწილს იღებთ. სთორი მონაცემებს ინახავს; თითოეული კომპონენტი სელექტორით ირჩევს ნაჭერს და ხელახლა მხოლოდ მაშინ რენდერდება, როცა ეს ნაჭერი იცვლება — ზუსტად ის ნაწილი, რომელიც სუფთა Context-ს აკლია.
import { create } from 'zustand' const useCart = create((set) => ({ items: [], add: (it) => set((s) => ({ items: [...s.items, it] })), })) // subscribe to ONE slice → re-render only when it changes const count = useCart((s) => s.items.length)

დაამატეთ ელემენტი და ხელახლა მხოლოდ Count რენდერდება — Avatar და Header სხვა ნაჭრებს კითხულობენ და უქმად რჩებიან.

ინსტრუმენტების ლანდშაფტი — კლიენტის სთორები

ოთხივე გაზიარების პრობლემას წყვეტს. ისინი სააზროვნო მოდელითა და ცერემონიის რაოდენობით განსხვავდებიან. თითო ხაზი დადებითზე, უარყოფითზე და იმაზე, როდის ჯდება თითოეული.

Zustand — პატარა, ჰუკის ფორმის სთორი

ერთი create გამოძახება ჰუკს აბრუნებს; არც პროვაიდერი, არც ბოილერპლეიტი. სელექტორები ჩაშენებულია. პრაგმატული ნაგულისხმევი არჩევანი აპლიკაციების უმეტესობისთვის 2026 წელს.

დადებითი
მინიმალური ბოილერპლეიტი; სელექტორებზე დაფუძნებული გამოწერები; React-ის გარეთაც მუშაობს.
უარყოფითი
მცირე კონვენციები — დიდმა გუნდებმა საკუთარი სტრუქტურა და დისციპლინა თავად უნდა დააწესონ.
აირჩიეთ, როცა
გინდათ საზიარო კლიენტის მდგომარეობა მინიმალური ცერემონიით — ჩვეულებრივი შემთხვევა.

Redux Toolkit (RTK) — Redux, ტკივილის გარეშე

ოფიციალური, თანამედროვე Redux. სლაისები ქმედებებსა და რედიუსერებს თქვენს ნაცვლად ქმნიან; ძლიერი კონვენციები, დროში მოგზაურობის DevTools და მიდლვეარების ეკოსისტემა.

დადებითი
პროგნოზირებადი პატერნები მასშტაბზე; შესანიშნავი DevTools; ერთი გაკვალული გზა დიდი გუნდებისთვის.
უარყოფითი
მეტი ცერემონია და უფრო დიდი ბანდლი, ვიდრე Zustand ან Jotai მარტივი საჭიროებებისთვის.
აირჩიეთ, როცა
დიდ გუნდს სჭირდება დაწესებული სტრუქტურა, აუდიტისთვის მოსახერხებელი ლოგიკა და ინსტრუმენტები.

Jotai — ატომები ქვემოდან ზემოთ

მდგომარეობა პატარა atom პრიმიტივებისგან იგება, რომლებიც ერთმანეთს ერწყმის; გამოთვლილი ატომები მხოლოდ მაშინ გადაითვლიან, როცა მათი შემავალი მონაცემები იცვლება. გრანულარული თავისი ბუნებით, React-ისთვის ბუნებრივი შეგრძნებით.

დადებითი
წვრილმარცვლოვანი განახლებები; გამოთვლილი მდგომარეობა ტრივიალურია; არ არსებობს ცენტრალური რედიუსერი, რომელიც გაიზრდება.
უარყოფითი
ბევრი პატარა ატომის კვალის დაჭერა შეიძლება რთული იყოს; ატომური მოდელი სააზროვნო გადართვას მოითხოვს.
აირჩიეთ, როცა
გაქვთ ბევრი დამოუკიდებელი, წვრილად გამოთვლილი UI მდგომარეობა.

Signals — წვრილმარცვლოვანი რეაქტიულობა

სიგნალი არის მნიშვნელობა, რომელიც პირდაპირ ატყობინებს თავის მკითხველებს და კომპონენტის დონის შედარებას გვერდს უვლის. მშობლიურია SolidJS-სა და Angular-ში; React-ში — Preact Signals-ის მეშვეობით. გრანულარული განახლებების მომავალი მიმართულება.

დადებითი
ქირურგიულად ზუსტი განახლებები — იცვლება მხოლოდ ის DOM-ბმულები, რომლებიც სიგნალს კითხულობენ.
უარყოფითი
ჯერ არ არის React-ისთვის იდიომატური; რენდერის მოდელთან შერევა კოგნიტურ დატვირთვას მატებს.
აირჩიეთ, როცა
სიგნალებზე აგებულ ფრეიმვორკზე ხართ, ან ძალიან მაღალ განახლების გამტარუნარიანობას მისდევთ.

პატიოსანი ნაგულისხმევი: თუ Context პლუს მდგომარეობის ცოტა აწევა ჯერ კიდევ მუშაობს, არცერთი მათგანი არ გჭირდებათ. როცა დაგჭირდებათ, Zustand ყველაზე პატარა ნაბიჯია წინ გუნდების უმეტესობისთვის.

04 · სერვერის ქეშები 6 წთ

სერვერის მდგომარეობა სთორის პრობლემა არ არის —
ის ქეშირების პრობლემაა.

წამოღებისთანავე ხელში გიჭირავთ ასლი, რომელიც შეიძლება არასწორი იყოს. სერვერის მდგომარეობის ბიბლიოთეკა ამ ასლს პატიოსანს ხდის: ის ერთნაირ მოთხოვნებს აერთიანებს, გასაღებით ქეშირებს, მყისიერად აბრუნებს ნაქეშირებულს და ფონურად ახლებს, და ინვალიდაციის ნათელ გზას გაძლევთ. იხილეთ ასევე Caching & CDNs ქეშირების საფუძვლებისთვის და API Design იმ ენდპოინტებისთვის, რომლებიც ამ გასაღებების უკან დგას.

Stale-while-revalidate — აჩვენე ნაქეშირებული (შესაძლოა დაძველებული) მნიშვნელობა მაშინვე, შემდეგ ფონურად ხელახლა წამოიღე და განაახლე, თუ შეიცვალა. UI მყისიერად აღიქმება და თანდათან ახალს უახლოვდება. ეს არის მთავარი ხრიკი ამ სლაიდის ყველა ინსტრუმენტის უკან.
const { data, isPending, error } = useQuery({ queryKey: ['todos', filter], // identity of this cache entry queryFn: () => fetchTodos(filter), staleTime: 30_000, // trust cache for 30s }) // after a mutation, mark the cache dirty so it refetches queryClient.invalidateQueries({ queryKey: ['todos'] })

ქეში მაშინვე პასუხობს (დაძველებულით), ფონურად ხელახლა წამოიღებს და შემდეგ ახალი მონაცემებით ხელახლა რენდერდება. შეკითხვის გასაღები თითოეული ქეშის ჩანაწერის იდენტობაა.

ინსტრუმენტების ლანდშაფტი — სერვერის მდგომარეობის ქეშები

ეს ქეშებია და არა სთორები. აირჩიეთ იმის მიხედვით, რამდენი გჭირდებათ და რას იყენებთ უკვე.

TanStack Query — სრულფასოვანი ნაგულისხმევი არჩევანი

ქეშირება, მოთხოვნების გაერთიანება, ფონური ხელახალი წამოღება, ხელახალი მცდელობები, პაგინაცია, ოპტიმისტური განახლებები და პირველხარისხოვანი DevTools. ბმულები React-ის, Vue-ს, Svelte-ს, Solid-ისა და სხვა ფრეიმვორკებისთვის.

დადებითი
ყველაფერი შიგნითაა; მუტაციები და ინვალიდაცია პირველხარისხოვანია; შესანიშნავი DevTools.
უარყოფითი
მეტი შესასწავლი ზედაპირი — გასაღებები, staleTime, ქეშის სიცოცხლის ხანგრძლივობა.
აირჩიეთ, როცა
სერვერის მდგომარეობა აპლიკაციის ბირთვია — უსაფრთხო ნაგულისხმევი არჩევანი 2026 წელს.

SWR — პატარა და ფოკუსირებული

Vercel-ისგან, დასახელებული stale-while-revalidate-ის მიხედვით. პატარაuseSWR(key, fetcher) ფარავს წამოღებას, ქეშირებასა და ხელახალ ვალიდაციას ძალიან მცირე API-თ.

დადებითი
მინიმალური API და ბანდლი; წაკითხვა ხელახალი ვალიდაციით პირდაპირ ყუთიდან მუშაობს.
უარყოფითი
მუტაციებისა და ქეშის მართვის უფრო თხელი ისტორია, ვიდრე TanStack Query-ს.
აირჩიეთ, როცა
ძირითადად წაკითხვები გაქვთ და ყველაზე მსუბუქი ინსტრუმენტი გინდათ — შესანიშნავად ჯდება Next.js-ზე.

RTK Query — სერვერის ქეში Redux-ის შიგნით

Redux Toolkit-ის ნაწილი. თქვენ აღწერთ ენდპოინტებს; ის ჰუკებს გენერირებს და ქეშს თქვენს Redux სთორში ინახავს, თეგებზე დაფუძნებული ინვალიდაციითა და თქვენი API-ს სქემიდან კოდის სურვილისამებრ გენერაციით.

დადებითი
ნულოვანი დამატებითი დამოკიდებულება, თუ Redux უკვე გიდგათ; ქეში კლიენტის მდგომარეობის გვერდით ცხოვრობს.
უარყოფითი
Redux-ზეა მიბმული; უხერხულია მხოლოდ წამოღებისთვის დანერგვა, თუ უკვე RTK-ზე არ ხართ.
აირჩიეთ, როცა
უკვე Redux Toolkit-ზე ხართ და ერთიანი, თანმიმდევრული სტეკი გინდათ.

როგორ ავირჩიოთ: უკვე RTK-ზე ხართ → RTK Query. მსუბუქი, ძირითადად წაკითხვები → SWR. რაიმე უფრო მდიდარი → TanStack Query. სამივე სჯობს ხელით აწყობილ useEffect წამოღებას.

05 · გამოთვლა და ნორმალიზაცია 4 წთ

ყველაზე იაფი მდგომარეობა ის არის,
რომელსაც არ ინახავთ.

ყოველი მნიშვნელობა, რომელსაც ინახავთ, შეიძლება სინქრონიდან გავიდეს. ორი ჩვევა ბაგების უმეტესობას აღკვეთს: გამოთვალეთ ყველაფერი, რისი გამოთვლაც არსებული მდგომარეობიდან შეგიძლიათ, და თითოეული ერთეულისთვის ერთი ჭეშმარიტების წყარო შეინარჩუნეთ, ასლების მიმოფანტვის ნაცვლად.

გამოთვლილი მდგომარეობა — მნიშვნელობა, რომელსაც რენდერის დროს არსებული მდგომარეობიდან თვლით, ცალკე შენახვის ნაცვლად. ჯამი, რაოდენობა, გაფილტრული სია. თუ მისი გამოთვლა უკვე არსებულიდან შეიძლება, გამოთვლილი ვერ დაძველდება — შენახული ასლი კი შეიძლება.
ორი ჭეშმარიტების წყარო
const [items, setItems] = useState([])
const [total, setTotal] = useState(0)  // duplicated truth

function add(it) {
  setItems([...items, it])
  setTotal(total + it.price)  // forget this once → out of sync
}
ერთი წყარო, დანარჩენი გამოთვლა
const [items, setItems] = useState([])
const total = items.reduce((s, it) => s + it.price, 0)

// expensive? memoize — still derived, just cached
const total = useMemo(
  () => heavySum(items), [items],
)

შეინახეთ items; დანარჩენი ყველაფერი მისი ფუნქციაა. useMemo-ს მხოლოდ მაშინ მიმართეთ, როცა გამოთვლა ნამდვილად ძვირია — ჯერ სისწორე, მერე წარმადობა.

დაანორმალიზეთ საზიარო ერთეულები

როცა ერთი და იგივე ერთეული ბევრ ადგილას ჩნდება, მისი ასლები ნუ ჩააშენებთ. შეინახეთ თითოეული ერთეული ერთხელ, id-ის მიხედვით, და მიუთითეთ მასზე. განაახლებთ ერთ ჩანაწერს და ყველა ხედი განახლდება — დასაწევი დაძველებული დუბლიკატები არ რჩება. ასე ფიქრობს მონაცემთა ბაზა და ამიტომაც აქვს Redux-ს ერთეულების ადაპტერი.

  • თითო სახლი თითო ერთეულზე, id-ის მიხედვით.
  • სიები id-ებს ინახავს და არა ჩაშენებულ ასლებს.
  • სერვერის მდგომარეობის ბიბლიოთეკები ამას ხშირად თქვენთვის მალავენ — მაგრამ პრინციპი მაინც კარნახობს, როგორი უნდა იყოს თქვენი გასაღებები.
// დუბლირებული — ავტორი ყოველ პოსტში კოპირდება { posts: [ { id: 1, author: { id: 9, name: 'Ada' } }, { id: 2, author: { id: 9, name: 'Ada' } }, ] } // ნორმალიზებული — თითო სახლი თითო ერთეულზე, id-ით მითითებული { posts: { 1: { id: 1, authorId: 9 }, 2: { id: 2, authorId: 9 } }, users: { 9: { id: 9, name: 'Ada' } } }

გადაარქვით Ada-ს სახელი ერთხელ users[9]-ში და ორივე პოსტი აისახავს — დასავიწყებელი დუბლიკატი არ არსებობს.

ერთი შენახული მასივი; ჯამი, რაოდენობა და გაფილტრული ხედები რენდერზე გამოითვლება — სინქრონში შესანარჩუნებელი არაფერია.

მარტივი წესი

  • ყოველ useState-ს ჰკითხეთ: ხომ არ შემიძლია ამის ნაცვლად გამოთვლა? თუ კი, ნუ შეინახავთ.
  • მდგომარეობის ორი ნაწილი, რომლებიც ყოველთვის უნდა თანხმდებოდნენ, მოსალოდნელი ბაგია — შეკუმშეთ ერთამდე.
  • დუბლირებული ერთეულები იგივე ხაფანგია მონაცემების მასშტაბზე — დაანორმალიზეთ.
06 · URL და ფორმები 4 წთ

მდგომარეობა, რომელიც გავიწყდებათ, რომ გაქვთ:
URL და თქვენი ფორმები.

სანამ ფილტრებისთვის ან ვიზარდისთვის სთორს დაამატებთ, შეამოწმეთ, ხომ არ ეკუთვნის ეს მდგომარეობა URL-ს ან ხომ არ რჩება ფორმის შიგნით. ორივე მდგომარეობის ნამდვილი კონტეინერია, რომელიც უკვე გაქვთ — და მათი გამოყენება ბაგების მთელ კატეგორიებს შლის.

URL-ის მდგომარეობა — მდგომარეობა, რომელიც გზასა და შეკითხვის სტრიქონშია ჩაწერილი, ამიტომ გასაზიარებელი, ჩასანიშნი და გადატვირთვისადმი გამძლეა. ფილტრები, დალაგება, მიმდინარე გვერდი, გახსნილი ტაბი, საძიებო სიტყვა: თუ მომხმარებელი მოელის, რომ ბმული ხედს აღადგენს, ეს URL-ს ეკუთვნის.
// Next.js App Router — read view state from the URL const params = useSearchParams() const sort = params.get('sort') ?? 'new' // write it back — shareable, refresh-proof, back-button-aware router.push('?sort=' + next) // libraries like nuqs add typed, ergonomic URL state

ჩადეთ ფილტრები და პაგინაცია შეკითხვის სტრიქონში და ბმული არის მდგომარეობა — სთორი აღარ სჭირდება და ყოველი ხედი გასაზიარებელია.

ფორმის მდგომარეობა ფორმაშივე რჩება

ფორმის დრაფტი დროებითი, ლოკალური კლიენტის მდგომარეობაა — გლობალურ სთორს იშვიათად ეკუთვნის. ნამდვილი არჩევანია კონტროლირებადი (React ფლობს ყოველ კლავიშს) vs არაკონტროლირებადი (მნიშვნელობას DOM ფლობს, React კი გაგზავნისას კითხულობს). არაკონტროლირებადი ფორმები გაცილებით ნაკლებად რენდერდება — სწორედ ამიტომ იხრებიან ფორმების ბიბლიოთეკები ამ მხარეს.

  • კონტროლირებადი — ყოველი კლავიში მდგომარეობაა. საჭიროა ცოცხალი ვალიდაციისთვის ან დამოკიდებული ველებისთვის; ხელახალი რენდერები უჯდება.
  • არაკონტროლირებადი — მნიშვნელობას DOM ინახავს; წაიკითხეთ გაგზავნისას. უფრო იაფი და მარტივი ჩვეულებრივი ფორმებისთვის.
  • მიმართეთ React Hook Form-ს ან TanStack Form-ს, როცა ფორმები სერიოზული გახდება — ვალიდაცია, მასივები, ასინქრონული შემოწმებები.
// react-hook-form — ნაგულისხმევად არაკონტროლირებადი, ცოტა რენდერი const { register, handleSubmit } = useForm() <form onSubmit={handleSubmit(save)}> <input {...register('email')} /> <input {...register('password')} /> </form> // React მნიშვნელობებს გაგზავნისას კითხულობს და არა ყოველ კლავიშზე

დრაფტს ფორმის ბიბლიოთეკა ფლობს. სთორამდე ან სერვერამდე ის მხოლოდ მაშინ აღწევს, როცა მომხმარებელი გაგზავნას დააჭერს.

07 · არჩევა და შეჯამება 4 წთ

ერთი კითხვა თითქმის ყველაფერს პასუხობს:
სად ცხოვრობს ეს მდგომარეობა?

არ არსებობს ერთი „მდგომარეობის მართვის ბიბლიოთეკა“ — არსებობს კატეგორიები და აპლიკაციების უმეტესობა რამდენიმეს ერთად იყენებს. მიმართეთ მდგომარეობის თითოეული ნაწილი მფლობელობის მიხედვით და არჩევანი თითქმის თავად კეთდება.

სერვერი, URL და ერთი ქვეხე მდგომარეობის უმეტესობას შთანთქავს. გლობალური კლიენტის სთორი უკანასკნელი გამოსავალია და არა პირველი.

წაიკითხეთ სქემა

  • სერვერზე ცხოვრობს? ეს ქეშია → TanStack Query ან SWR. სთორში ნუ ჩადებთ.
  • ბმულმა უნდა აღადგინოს? URL-ის საძიებო პარამეტრები.
  • ერთი კომპონენტი ან ქვეხე იყენებს? useState/useReducer, ასწიეთ მხოლოდ იმდენად, რამდენადაც საჭიროა.
  • ნამდვილად მთელი აპლიკაციის კლიენტის მდგომარეობაა? მხოლოდ ახლა სთორი — ნაგულისხმევად Zustand.

Redux Toolkit კვლავ შესანიშნავია დიდი გუნდებისთვის, რომლებსაც დაწესებული სტრუქტურა და აუდიტისთვის მოსახერხებელი ლოგიკა სურთ. მაგრამ ისტორიულად Redux-ის დიდი ნაწილი სინამდვილეში სერვერის მდგომარეობა იყო — და ეს საქმე ახლა შეკითხვების ქეშს ეკუთვნის. ჯერ ეს ორი გამიჯნეთ; ბევრი აპლიკაცია აღმოაჩენს, რომ გლობალური კლიენტის მდგომარეობა თითქმის არ სჭირდება.

ხუთი წესი, რომელიც თან უნდა წაიღოთ

1გამიჯნეთ კლიენტისა და სერვერის მდგომარეობა. ყველა სხვა გადაწყვეტილება ამაზეა ჩამოკიდებული.
2სერვერის მდგომარეობა ქეშია — გამოიყენეთ შეკითხვების ბიბლიოთეკა და არასდროს useState + useEffect.
3დაიწყეთ ლოკალურად. useState → აწევა → Context → სთორი სელექტორებით — მხოლოდ იმდენად, რამდენადაც საჭიროება ჩნდება.
4გამოთვალეთ, ნუ დუბლირებთ. ერთი ჭეშმარიტების წყარო; საზიარო ერთეულები id-ით დაანორმალიზეთ.
5გამოიყენეთ კონტეინერები, რომლებიც უკვე გაქვთ — URL გასაზიარებელი ხედისთვის, ფორმა დრაფტებისთვის.
ცოდნის შემოწმება

დაგამახსოვრდათ?

ხუთი სწრაფი კითხვა კლიენტი/სერვერის გაყოფაზე, Context-ზე, სთორებზე, ქეშირებასა და იმაზე, სად ეკუთვნის მდგომარეობა — მყისიერი უკუკავშირი, ავტორიზაციის გარეშე.

შეაფასეთ ეს დასტა
იყავით პირველი

ნავიგაცია ← → ღილაკებით ან სქროლით · უკან ბიბლიოთეკაში