From 71a8d0f87a91de10531091559f3966accf2f6c72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rado=C5=A1=20Mili=C4=87ev?= <40705899+rammba@users.noreply.github.com> Date: Tue, 13 May 2025 17:11:16 +0200 Subject: [PATCH] Translate sharing-state-between-components.md --- .../learn/sharing-state-between-components.md | 208 +++++++++--------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/src/content/learn/sharing-state-between-components.md b/src/content/learn/sharing-state-between-components.md index 52eaf28f..b59ade26 100644 --- a/src/content/learn/sharing-state-between-components.md +++ b/src/content/learn/sharing-state-between-components.md @@ -1,31 +1,31 @@ --- -title: Sharing State Between Components +title: Deljenje state-a između komponenata --- -Sometimes, you want the state of two components to always change together. To do it, remove state from both of them, move it to their closest common parent, and then pass it down to them via props. This is known as *lifting state up,* and it's one of the most common things you will do writing React code. +Ponekad želite da se state-ovi dve komponente menjaju zajedno. Da biste to uradili, uklonite state iz obe komponente, pomerite ga u najbližeg zajedničkog roditelja i prosledite ga nazad kroz props. Ovo je poznato kao *podizanje state-a* i jedna je od najčešćih stvari koje ćete pisati u React kodu. -- How to share state between components by lifting it up -- What are controlled and uncontrolled components +- Kako da podizanjem delite state između komponenata +- Šta su kontrolisane i nekontrolisane komponente -## Lifting state up by example {/*lifting-state-up-by-example*/} +## Podizanje state-a uz primer {/*lifting-state-up-by-example*/} -In this example, a parent `Accordion` component renders two separate `Panel`s: +U ovom primeru, roditeljska `Accordion` komponenta renderuje dva različita `Panel`-a: * `Accordion` - `Panel` - `Panel` -Each `Panel` component has a boolean `isActive` state that determines whether its content is visible. +Svaka `Panel` komponenta ima boolean `isActive` state koji određuje da li je sadržaj vidljiv. -Press the Show button for both panels: +Pritisnite dugme "Prikaži" na oba panel-a: @@ -41,7 +41,7 @@ function Panel({ title, children }) {

{children}

) : ( )} @@ -51,12 +51,12 @@ function Panel({ title, children }) { export default function Accordion() { return ( <> -

Almaty, Kazakhstan

- - With a population of about 2 million, Almaty is Kazakhstan's largest city. From 1929 to 1997, it was its capital city. +

Almati, Kazahstan

+ + Sa populacijom od oko 2 miliona, Almati je najveći grad u Kazahstanu. Bio je glavni grad od 1929. do. 1997. godine. - - The name comes from алма, the Kazakh word for "apple" and is often translated as "full of apples". In fact, the region surrounding Almaty is thought to be the ancestral home of the apple, and the wild Malus sieversii is considered a likely candidate for the ancestor of the modern domestic apple. + + Ime potiče od reči алма, što na kazaškom jeziku znači "jabuka", i često se prevodi kao "pun jabuka". U suštini, region koji okružuje Almati se smatra pradomovinom jabuka, a divlja Malus sieversii se smatra mogućim pretkom moderne domaće jabuke. ); @@ -73,59 +73,59 @@ h3, p { margin: 5px 0px; }
-Notice how pressing one panel's button does not affect the other panel--they are independent. +Primetite kako pritiskanje dugmeta u jednom panel-u ne utiče na drugi--oni su nezavisni. - + -Initially, each `Panel`'s `isActive` state is `false`, so they both appear collapsed +Inicijalno, `isActive` state svakog `Panel`-a je `false`, tako da su oba sklopljena - + -Clicking either `Panel`'s button will only update that `Panel`'s `isActive` state alone +Klik na dugme bilo kog `Panel`-a će ažurirati samo `isActive` state tog `Panel`-a -**But now let's say you want to change it so that only one panel is expanded at any given time.** With that design, expanding the second panel should collapse the first one. How would you do that? +**Ali, recimo da to želite promeniti tako da samo jedan panel može biti proširen.** Sa takvim dizajnom, proširivanje drugog panel-a bi trebalo da sklopi prvi. Kako biste to uradili? -To coordinate these two panels, you need to "lift their state up" to a parent component in three steps: +Da biste koordinisali ta dva panel-a, potrebno je da "podignete njihov state" u roditeljsku komponentu u ova tri koraka: -1. **Remove** state from the child components. -2. **Pass** hardcoded data from the common parent. -3. **Add** state to the common parent and pass it down together with the event handlers. +1. **Ukloniti** state iz dečjih komponenata. +2. **Proslediti** hardkodirane podatke iz zajedničkog roditelja. +3. **Dodati** state u zajedničkog roditelja i proslediti ga zajedno sa event handler-ima. -This will allow the `Accordion` component to coordinate both `Panel`s and only expand one at a time. +Ovo će omogućiti `Accordion` komponenti da koordiniše oba `Panel`-a i proširi samo jedan. -### Step 1: Remove state from the child components {/*step-1-remove-state-from-the-child-components*/} +### Korak 1: Ukloniti state iz dečjih komponenata {/*step-1-remove-state-from-the-child-components*/} -You will give control of the `Panel`'s `isActive` to its parent component. This means that the parent component will pass `isActive` to `Panel` as a prop instead. Start by **removing this line** from the `Panel` component: +Daćete kontrolu nad `isActive` iz `Panel`-a njegovoj roditeljskoj komponenti. Ovo znači da će roditeljska komponenta proslediti `isActive` u `Panel` kao prop. Počnite sa **uklanjanjem ove linije** iz `Panel` komponente: ```js const [isActive, setIsActive] = useState(false); ``` -And instead, add `isActive` to the `Panel`'s list of props: +I umesto toga, dodajte `isActive` u listu props-a u `Panel`-u: ```js function Panel({ title, children, isActive }) { ``` -Now the `Panel`'s parent component can *control* `isActive` by [passing it down as a prop.](/learn/passing-props-to-a-component) Conversely, the `Panel` component now has *no control* over the value of `isActive`--it's now up to the parent component! +Sada roditeljska komponenta `Panel`-a može *kontrolisati* `isActive` [prosleđivanjem prop-a](/learn/passing-props-to-a-component). Sa druge strane, `Panel` komponenta sada *nema kontrolu* nad vrednošću `isActive`--sada je to na roditeljskoj komponenti! -### Step 2: Pass hardcoded data from the common parent {/*step-2-pass-hardcoded-data-from-the-common-parent*/} +### Korak 2: Proslediti hardkodirane podatke iz zajedničkog roditelja {/*step-2-pass-hardcoded-data-from-the-common-parent*/} -To lift state up, you must locate the closest common parent component of *both* of the child components that you want to coordinate: +Da biste podigli state morate locirati najbližu zajedničku roditeljsku komponentu *obe* dečje komponente koje želite da koordinišete: -* `Accordion` *(closest common parent)* +* `Accordion` *(najbliži zajednički roditelj)* - `Panel` - `Panel` -In this example, it's the `Accordion` component. Since it's above both panels and can control their props, it will become the "source of truth" for which panel is currently active. Make the `Accordion` component pass a hardcoded value of `isActive` (for example, `true`) to both panels: +U ovom primeru, to je `Accordion` komponenta. Pošto je iznad oba panel-a i može da kontroliše njihove props-e, postaće "izvor istine" označavajući koji panel je trenutno aktivan. Napravite da `Accordion` komponenta prosledi hardkodiranu vrednost za `isActive` (na primer, `true`) u oba panel-a: @@ -135,12 +135,12 @@ import { useState } from 'react'; export default function Accordion() { return ( <> -

Almaty, Kazakhstan

- - With a population of about 2 million, Almaty is Kazakhstan's largest city. From 1929 to 1997, it was its capital city. +

Almati, Kazahstan

+ + Sa populacijom od oko 2 miliona, Almati je najveći grad u Kazahstanu. Bio je glavni grad od 1929. do. 1997. godine. - - The name comes from алма, the Kazakh word for "apple" and is often translated as "full of apples". In fact, the region surrounding Almaty is thought to be the ancestral home of the apple, and the wild Malus sieversii is considered a likely candidate for the ancestor of the modern domestic apple. + + Ime potiče od reči алма, što na kazaškom jeziku znači "jabuka", i često se prevodi kao "pun jabuka". U suštini, region koji okružuje Almati se smatra pradomovinom jabuka, a divlja Malus sieversii se smatra mogućim pretkom moderne domaće jabuke. ); @@ -154,7 +154,7 @@ function Panel({ title, children, isActive }) {

{children}

) : ( )} @@ -172,21 +172,21 @@ h3, p { margin: 5px 0px; }
-Try editing the hardcoded `isActive` values in the `Accordion` component and see the result on the screen. +Pokušajte da promenite hardkodirane `isActive` vrednosti u `Accordion` komponenti da vidite rezultat na ekranu. -### Step 3: Add state to the common parent {/*step-3-add-state-to-the-common-parent*/} +### Korak 3: Dodati state u zajedničkog roditelja {/*step-3-add-state-to-the-common-parent*/} -Lifting state up often changes the nature of what you're storing as state. +Podizanje state-a često menja prirodu onoga što čuvate kao state. -In this case, only one panel should be active at a time. This means that the `Accordion` common parent component needs to keep track of *which* panel is the active one. Instead of a `boolean` value, it could use a number as the index of the active `Panel` for the state variable: +U ovom slučaju, samo jedan panel treba biti aktivan. To znači da zajednička roditeljska `Accordion` komponenta treba da prati *koji* panel je aktivan. Umesto `boolean` vrednosti može se koristiti broj kao indeks aktivnog `Panel`-a u state promenljivoj: ```js const [activeIndex, setActiveIndex] = useState(0); ``` -When the `activeIndex` is `0`, the first panel is active, and when it's `1`, it's the second one. +Kada je `activeIndex` jednak `0`, prvi panel je aktivan, a kada je `1`, aktivan je drugi. -Clicking the "Show" button in either `Panel` needs to change the active index in `Accordion`. A `Panel` can't set the `activeIndex` state directly because it's defined inside the `Accordion`. The `Accordion` component needs to *explicitly allow* the `Panel` component to change its state by [passing an event handler down as a prop](/learn/responding-to-events#passing-event-handlers-as-props): +Klik na dugme "Prikaži" u bilo kom `Panel`-u treba da promeni aktivan indeks u `Accordion`-u. `Panel` ne može da postavi `activeIndex` state direktno pošto je on definisan unutar `Accordion`-a. `Accordion` komponenta mora da *eksplicitno dozvoli* `Panel` komponenti da menja njen state [prosleđivanjem event handler-a kao prop-a](/learn/responding-to-events#passing-event-handlers-as-props): ```js <> @@ -205,7 +205,7 @@ Clicking the "Show" button in either `Panel` needs to change the active index in ``` -The ` )} @@ -266,19 +266,19 @@ h3, p { margin: 5px 0px; } -This completes lifting state up! Moving state into the common parent component allowed you to coordinate the two panels. Using the active index instead of two "is shown" flags ensured that only one panel is active at a given time. And passing down the event handler to the child allowed the child to change the parent's state. +Ovim se zaokružuje podizanje state-a! Pomeranje state-a u zajedničku roditeljsku komponentu vam je omogućilo da koordinišete sa dva panel-a. Upotreba aktivnog indeksa umesto dva "da li je prikazano" flag-a osigurava da je samo jedan panel aktivan. Prosleđivanje event handler-a u dečje komponente je omogućilo deci da promene roditeljski state. - + -Initially, `Accordion`'s `activeIndex` is `0`, so the first `Panel` receives `isActive = true` +Inicijalno, `Accordion`-ov `activeIndex` je `0`, pa prvi `Panel` prima `isActive = true` - + -When `Accordion`'s `activeIndex` state changes to `1`, the second `Panel` receives `isActive = true` instead +Kada se `activeIndex` state u `Accordion`-u promeni na `1`, drugi panel `Panel` prima `isActive = true` umesto prvog @@ -286,48 +286,48 @@ When `Accordion`'s `activeIndex` state changes to `1`, the second `Panel` receiv -#### Controlled and uncontrolled components {/*controlled-and-uncontrolled-components*/} +#### Kontrolisane i nekontrolisane komponente {/*controlled-and-uncontrolled-components*/} -It is common to call a component with some local state "uncontrolled". For example, the original `Panel` component with an `isActive` state variable is uncontrolled because its parent cannot influence whether the panel is active or not. +Uobičajeno je komponente sa lokalnim state-om nazivati "nekontrolisanim". Na primer, originalna `Panel` komponenta sa `isActive` state promenljivom je nekontrolisana jer njen roditelj ne može da utiče da li je panel aktivan ili ne. -In contrast, you might say a component is "controlled" when the important information in it is driven by props rather than its own local state. This lets the parent component fully specify its behavior. The final `Panel` component with the `isActive` prop is controlled by the `Accordion` component. +Suprotno od toga, možete reći da je komponenta "kontrolisana" kada su bitne informacije u njoj vođene props-ima umesto njenim lokalnim state-om. Ovo omogućava roditeljskoj komponenti da potpuno specificira njeno ponašanje. Konačna `Panel` komponenta sa `isActive` prop-om je kontrolisana od strane `Accordion` komponente. -Uncontrolled components are easier to use within their parents because they require less configuration. But they're less flexible when you want to coordinate them together. Controlled components are maximally flexible, but they require the parent components to fully configure them with props. +Nekontrolisane komponente je lakše koristiti unutar njihovih roditelja jer zahtevaju manje konfiguracije. Ali, one su manje fleksibilne ako želite da ih koordinišete. Kontrolisane komponente su maksimalno fleksibilne, ali zahtevaju da ih roditeljske komponente u potpunosti konfigurišu preko props-a. -In practice, "controlled" and "uncontrolled" aren't strict technical terms--each component usually has some mix of both local state and props. However, this is a useful way to talk about how components are designed and what capabilities they offer. +U praksi, "kontrolisano" i "nekontrolisano" nisu striktno tehnički termini--svaka komponenta obično ima neku kombinaciju lokalnog state-a i props-a. Međutim, ovo je koristan način da pričamo o tome kako su komponente dizajnirane i koje sposobnosti pružaju. -When writing a component, consider which information in it should be controlled (via props), and which information should be uncontrolled (via state). But you can always change your mind and refactor later. +Kada god pišete komponentu, razmotrite koje informacije trebaju biti kontrolisane (kroz props), a koje informacije trebaju biti nekontrolisane (kroz state). Ali, uvek se možete predomisliti i refaktorisati kasnije. -## A single source of truth for each state {/*a-single-source-of-truth-for-each-state*/} +## Jedan izvor istine za svaki state {/*a-single-source-of-truth-for-each-state*/} -In a React application, many components will have their own state. Some state may "live" close to the leaf components (components at the bottom of the tree) like inputs. Other state may "live" closer to the top of the app. For example, even client-side routing libraries are usually implemented by storing the current route in the React state, and passing it down by props! +U React aplikaciji, mnoge komponente će imati svoj state. Poneki state može "živeti" u blizini listova (komponenti na dnu stabla) poput input-a. Drugi state može "živeti" bliže vrhu aplikacije. Na primer, čak su i biblioteke za rutiranje na klijentskoj strani često implementirane da čuvaju trenutnu rutu u React state-u, i da je prosleđuju deci kroz props! -**For each unique piece of state, you will choose the component that "owns" it.** This principle is also known as having a ["single source of truth".](https://en.wikipedia.org/wiki/Single_source_of_truth) It doesn't mean that all state lives in one place--but that for _each_ piece of state, there is a _specific_ component that holds that piece of information. Instead of duplicating shared state between components, *lift it up* to their common shared parent, and *pass it down* to the children that need it. +**Za svaki jedinstveni deo state-a, izabraćete komponentu koja ga "poseduje".** Ovaj princip je poznat i kao ["jedan izvor istine"](https://en.wikipedia.org/wiki/Single_source_of_truth). To ne znači da svi state-ovi žive na jednom mestu--već da za _svaki_ deo state-a postoji _posebna_ komponenta koja drži tu informaciju. Umesto da duplirate deljeni state između komponenata, *podignite ga* u njihovog zajedničkog roditelja, koji će onda *proslediti* taj state deci kojima je potreban. -Your app will change as you work on it. It is common that you will move state down or back up while you're still figuring out where each piece of the state "lives". This is all part of the process! +Vaša aplikacija će se menjati dok radite na njoj. Uobičajeno je da ćete pomerati state gore-dole dok pokušavate da shvatite gde svaki deo state-a "živi". Sve je to deo procesa! -To see what this feels like in practice with a few more components, read [Thinking in React.](/learn/thinking-in-react) +Da biste videli kako ovo izgleda u praksi sa nekoliko komponenata, pročitajte [Razmišljanje u React-u](/learn/thinking-in-react). -* When you want to coordinate two components, move their state to their common parent. -* Then pass the information down through props from their common parent. -* Finally, pass the event handlers down so that the children can change the parent's state. -* It's useful to consider components as "controlled" (driven by props) or "uncontrolled" (driven by state). +* Kada želite da koordinišete dve komponente, pomerite njihov state u zajedničkog roditelja. +* Onda, prosledite tu informaciju iz zajedničkog roditelja kroz props. +* Na kraju, prosledite event handler-e kako bi deca mogla menjati roditeljski state. +* Korisno je smatrati komponente "kontrolisanim" (vođene props-ima) ili "nekontrolisanim" (vođene state-om). -#### Synced inputs {/*synced-inputs*/} +#### Sinhronizovani input-i {/*synced-inputs*/} -These two inputs are independent. Make them stay in sync: editing one input should update the other input with the same text, and vice versa. +Ova dva input-a su nezavisna. Sinhronizujte ih: izmena jednog input-a treba da postavi isti tekst u drugi input, i obrnuto. -You'll need to lift their state up into the parent component. +Potrebno je da podignete state u roditeljsku komponentu. @@ -339,8 +339,8 @@ import { useState } from 'react'; export default function SyncedInputs() { return ( <> - - + + ); } @@ -374,7 +374,7 @@ label { display: block; } -Move the `text` state variable into the parent component along with the `handleChange` handler. Then pass them down as props to both of the `Input` components. This will keep them in sync. +Pomerite `text` state promenljivu u roditeljsku komponentu zajedno sa `handleChange` handler-om. Onda ih prosledite kao props u obe `Input` komponente. Ovo će ih sinhronizovati. @@ -391,12 +391,12 @@ export default function SyncedInputs() { return ( <> @@ -427,17 +427,17 @@ label { display: block; } -#### Filtering a list {/*filtering-a-list*/} +#### Filtrirati listu {/*filtering-a-list*/} -In this example, the `SearchBar` has its own `query` state that controls the text input. Its parent `FilterableList` component displays a `List` of items, but it doesn't take the search query into account. +U ovom primeru, `SearchBar` ima sopstveni `query` state koji kontroliše tekstualni input. Njegova roditeljska `FilterableList` komponenta prikazuje `List`-u elemenata, ali za pretragu ne uzima u obzir uneti upit. -Use the `filterItems(foods, query)` function to filter the list according to the search query. To test your changes, verify that typing "s" into the input filters down the list to "Sushi", "Shish kebab", and "Dim sum". +Iskoristite `filterItems(foods, query)` funkciju da filtrirate listu u zavisnosti od upita za pretragu. Da biste testirali izmene, uverite se da unosom "d" u input filtrirate listu na "Dal" i "Dim sum". -Note that `filterItems` is already implemented and imported so you don't need to write it yourself! +Primetite da je `filterItems` već implementirana i import-ovana tako da to ne morate sami raditi! -You will want to remove the `query` state and the `handleChange` handler from the `SearchBar`, and move them to the `FilterableList`. Then pass them down to `SearchBar` as `query` and `onChange` props. +Želećete da uklonite `query` state i `handleChange` handler iz `SearchBar`-a i da ih pomerite u `FilterableList`. Onda ih prosledite u `SearchBar` kao `query` i `onChange` props-e. @@ -466,7 +466,7 @@ function SearchBar() { return (