From 4c78e8d1d025c7f50f1bffea189244184c93c627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Paj=C4=85k?= Date: Sat, 22 Mar 2025 20:22:29 +0100 Subject: [PATCH 1/2] docs: translate escape hatches - referencing values with refs --- .../learn/referencing-values-with-refs.md | 219 +++++++++--------- src/sidebarLearn.json | 2 +- 2 files changed, 111 insertions(+), 110 deletions(-) diff --git a/src/content/learn/referencing-values-with-refs.md b/src/content/learn/referencing-values-with-refs.md index 4faf18786..f72d5ef9b 100644 --- a/src/content/learn/referencing-values-with-refs.md +++ b/src/content/learn/referencing-values-with-refs.md @@ -1,49 +1,49 @@ --- -title: 'Referencing Values with Refs' +title: 'Odwoływanie się do wartości za pomocą referencji' --- -When you want a component to "remember" some information, but you don't want that information to [trigger new renders](/learn/render-and-commit), you can use a *ref*. +Gdy chcesz, aby komponent "zapamiętał" pewne informacje, ale nie chcesz, aby te informacje [wywoływały ponowne renderowania](/learn/render-and-commit), możesz użyć *referencji*. -- How to add a ref to your component -- How to update a ref's value -- How refs are different from state -- How to use refs safely +- Jak dodać referencję do komponentu +- Jak zaktualizować wartość referencji +- Czym referencje różnią się od stanu +- Jak bezpiecznie używać referencji -## Adding a ref to your component {/*adding-a-ref-to-your-component*/} +## Dodawanie referencji do komponentu {/*adding-a-ref-to-your-component*/} -You can add a ref to your component by importing the `useRef` Hook from React: +Możesz dodać referencję do swojego komponentu, importując hook `useRef` z Reacta: ```js import { useRef } from 'react'; ``` -Inside your component, call the `useRef` Hook and pass the initial value that you want to reference as the only argument. For example, here is a ref to the value `0`: +We wnętrzu swojego komponentu wywołaj hook `useRef`, przekazując jako jedyny argument początkową wartość, do której chcesz się odwoływać. Na przykład, oto referencja do wartości `0`: ```js const ref = useRef(0); ``` -`useRef` returns an object like this: +`useRef` zwraca obiekt o następującej strukturze: ```js { - current: 0 // The value you passed to useRef + current: 0 // Wartość, którą przekazałeś do useRef } ``` - + -You can access the current value of that ref through the `ref.current` property. This value is intentionally mutable, meaning you can both read and write to it. It's like a secret pocket of your component that React doesn't track. (This is what makes it an "escape hatch" from React's one-way data flow--more on that below!) +Możesz uzyskać dostęp do bieżącej wartości tej referencji przez właściwość `ref.current`. Ta wartość jest celowo mutowalna, co oznacza, że możesz zarówno ją odczytywać, jak i zapisywać. To jak tajna kieszeń twojego komponentu, której React nie śledzi. (To właśnie sprawia, że jest to "wyjście awaryjne" z jednokierunkowego przepływu danych Reacta - więcej na ten temat poniżej!) -Here, a button will increment `ref.current` on every click: +Tutaj, przycisk będzie inkrementować `ref.current` przy każdym kliknięciu: @@ -55,12 +55,12 @@ export default function Counter() { function handleClick() { ref.current = ref.current + 1; - alert('You clicked ' + ref.current + ' times!'); + alert('Kliknąłeś ' + ref.current + ' razy!'); } return ( ); } @@ -68,20 +68,20 @@ export default function Counter() { -The ref points to a number, but, like [state](/learn/state-a-components-memory), you could point to anything: a string, an object, or even a function. Unlike state, ref is a plain JavaScript object with the `current` property that you can read and modify. +Referencja wskazuje na liczbę, ale podobnie jak [stan](/learn/state-a-components-memory), możesz wskazać na cokolwiek: ciąg znaków, obiekt, a nawet funkcję. W przeciwieństwie do stanu, referencja to zwykły obiekt JavaScript z właściwością `current`, którą możesz odczytać i modyfikować. -Note that **the component doesn't re-render with every increment.** Like state, refs are retained by React between re-renders. However, setting state re-renders a component. Changing a ref does not! +Zwróć uwagę, że **komponent nie renderuje się ponownie przy każdej inkrementacji.** Podobnie jak stan, referencje są przechowywane przez Reacta między przerenderowaniami. Jednak ustawienie stanu powoduje ponowne renderowanie komponentu, a zmiana referencji - nie! -## Example: building a stopwatch {/*example-building-a-stopwatch*/} +## Przykład: budowanie stoperu {/*example-building-a-stopwatch*/} -You can combine refs and state in a single component. For example, let's make a stopwatch that the user can start or stop by pressing a button. In order to display how much time has passed since the user pressed "Start", you will need to keep track of when the Start button was pressed and what the current time is. **This information is used for rendering, so you'll keep it in state:** +Możesz połączyć referencje i stan w jednym komponencie. Na przykład, zbudujmy stoper, który użytkownik może uruchomić lub zatrzymać, naciskając przycisk. Aby wyświetlić, ile czasu minęło od momentu naciśnięcia przycisku "Start", musisz śledzić, kiedy przycisk Start został naciśnięty i jaki jest bieżący czas. **Te informacje są używane do renderowania, dlatego będziesz przechowywać je w stanie:** ```js const [startTime, setStartTime] = useState(null); const [now, setNow] = useState(null); ``` -When the user presses "Start", you'll use [`setInterval`](https://developer.mozilla.org/docs/Web/API/setInterval) in order to update the time every 10 milliseconds: +Kiedy użytkownik naciśnie "Start", użyjesz metody [`setInterval`](https://developer.mozilla.org/docs/Web/API/setInterval), aby aktualizować czas co 10 milisekund: @@ -93,12 +93,12 @@ export default function Stopwatch() { const [now, setNow] = useState(null); function handleStart() { - // Start counting. + // Rozpoczęcie odliczania. setStartTime(Date.now()); setNow(Date.now()); setInterval(() => { - // Update the current time every 10ms. + // Zaktualizowanie bieżącego czasu co 10 ms. setNow(Date.now()); }, 10); } @@ -110,7 +110,7 @@ export default function Stopwatch() { return ( <> -

Time passed: {secondsPassed.toFixed(3)}

+

Minęło: {secondsPassed.toFixed(3)}

@@ -121,7 +121,7 @@ export default function Stopwatch() {
-When the "Stop" button is pressed, you need to cancel the existing interval so that it stops updating the `now` state variable. You can do this by calling [`clearInterval`](https://developer.mozilla.org/en-US/docs/Web/API/clearInterval), but you need to give it the interval ID that was previously returned by the `setInterval` call when the user pressed Start. You need to keep the interval ID somewhere. **Since the interval ID is not used for rendering, you can keep it in a ref:** +Kiedy przycisk "Stop" zostanie naciśnięty, musisz anulować istniejący interwał, aby przestał aktualizować zmienną stanu now. Możesz to zrobić, wywołując metodę [`clearInterval`](https://developer.mozilla.org/en-US/docs/Web/API/clearInterval), ale musisz przekazać mu identyfikator interwału, który został wcześniej zwrócony przez wywołanie metody `setInterval` po naciśnięciu przycisku Start. Musisz przechować identyfikator interwału w jakimś miejscu. **Ponieważ identyfikator interwału nie jest używany do renderowania, możesz przechować go w referencji:** @@ -154,7 +154,7 @@ export default function Stopwatch() { return ( <> -

Time passed: {secondsPassed.toFixed(3)}

+

Minęło: {secondsPassed.toFixed(3)}

@@ -168,20 +168,20 @@ export default function Stopwatch() {
-When a piece of information is used for rendering, keep it in state. When a piece of information is only needed by event handlers and changing it doesn't require a re-render, using a ref may be more efficient. +Jeśli dana informacja jest wykorzystywana podczas renderowania, przechowuj ją w stanie. Kiedy informacja jest potrzebna tylko przez obsługiwacze zdarzeń i jej zmiana nie wymaga ponownego renderowania, użycie referencji może być bardziej wydajne. -## Differences between refs and state {/*differences-between-refs-and-state*/} +## Różnice między referencjami a stanem {/*differences-between-refs-and-state*/} -Perhaps you're thinking refs seem less "strict" than state—you can mutate them instead of always having to use a state setting function, for instance. But in most cases, you'll want to use state. Refs are an "escape hatch" you won't need often. Here's how state and refs compare: +Możesz pomyśleć, że referencje wydają się mniej "rygorystyczne" niż stan – na przykład pozwalają na mutowanie wartości bez konieczności używania funkcji do ustawiania stanu. Jednak w większości przypadków będziesz chciał używać stanu. Referencje to "wyjście awaryjne", które rzadko będziesz wykorzystywać. Oto porównanie stanu i referencji: -| refs | state | -| ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | -| `useRef(initialValue)` returns `{ current: initialValue }` | `useState(initialValue)` returns the current value of a state variable and a state setter function ( `[value, setValue]`) | -| Doesn't trigger re-render when you change it. | Triggers re-render when you change it. | -| Mutable—you can modify and update `current`'s value outside of the rendering process. | "Immutable"—you must use the state setting function to modify state variables to queue a re-render. | -| You shouldn't read (or write) the `current` value during rendering. | You can read state at any time. However, each render has its own [snapshot](/learn/state-as-a-snapshot) of state which does not change. +| refs | state | +|---------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------| +| `useRef(initialValue)` zwraca `{ current: initialValue }` | `useState(initialValue)` zwraca bieżącą wartość zmiennej stanu oraz funkcję ustawiającą stan (`[value, setValue]`) | +| Nie wywołuje ponownego renderowania, gdy go zmienisz. | Wywołuje ponowne renderowanie, gdy go zmienisz. | +| "Mutowalny" - możesz modyfikować i aktualizować wartość current poza procesem renderowania. | "Niemutowalny" - musisz używać funkcji ustawiającej stan, aby modyfikować zmienne stanu i zainicjować kolejne renderowanie. | +| Nie powinieneś odczytywać (ani zapisywać) wartości `current` podczas renderowania. | Możesz odczytać stan w dowolnym momencie. Jednak każde renderowanie ma swoją własną [migawkę](/learn/state-as-a-snapshot) stanu, która nie zmienia się. | -Here is a counter button that's implemented with state: +Oto przycisk licznika zaimplementowany za pomocą stanu: @@ -197,7 +197,7 @@ export default function Counter() { return ( ); } @@ -205,9 +205,9 @@ export default function Counter() { -Because the `count` value is displayed, it makes sense to use a state value for it. When the counter's value is set with `setCount()`, React re-renders the component and the screen updates to reflect the new count. +Ponieważ wartość `count` jest wyświetlana, ma sens użycie zmiennej stanu do jej przechowywania. Kiedy wartość licznika jest ustawiana za pomocą `setCount()`, React ponownie renderuje komponent, a ekran jest aktualizowany, aby odzwierciedlić nową wartość licznika. -If you tried to implement this with a ref, React would never re-render the component, so you'd never see the count change! See how clicking this button **does not update its text**: +Gdybyś próbował zaimplementować to za pomocą referencji, React nigdy nie przerenderowałby ponownie komponentu, więc nigdy nie zobaczyłbyś zmiany licznika! Zobacz, że kliknięcie tego przycisku **nie aktualizuje jego tekstu**: @@ -218,13 +218,13 @@ export default function Counter() { let countRef = useRef(0); function handleClick() { - // This doesn't re-render the component! + // To nie przerenderowuje komponentu! countRef.current = countRef.current + 1; } return ( ); } @@ -232,68 +232,68 @@ export default function Counter() { -This is why reading `ref.current` during render leads to unreliable code. If you need that, use state instead. +Dlatego odczytywanie `ref.current` podczas renderowania prowadzi do niepewnego kodu. Jeśli tego potrzebujesz, użyj stanu zamiast referencji. -#### How does useRef work inside? {/*how-does-use-ref-work-inside*/} +#### Jak działa useRef wewnątrz?? {/*how-does-use-ref-work-inside*/} -Although both `useState` and `useRef` are provided by React, in principle `useRef` could be implemented _on top of_ `useState`. You can imagine that inside of React, `useRef` is implemented like this: +Chociaż zarówno `useState`, jak i `useRef` są udostępniane przez React, w zasadzie `useRef` mogłoby być zaimplementowane na bazie `useState`. Możesz sobie wyobrazić, że wewnątrz Reacta, `useRef` jest zaimplementowane w ten sposób: ```js -// Inside of React +// Wewnątrz Reacta function useRef(initialValue) { const [ref, unused] = useState({ current: initialValue }); return ref; } ``` -During the first render, `useRef` returns `{ current: initialValue }`. This object is stored by React, so during the next render the same object will be returned. Note how the state setter is unused in this example. It is unnecessary because `useRef` always needs to return the same object! +Podczas pierwszego renderowania, `useRef` zwraca `{ current: initialValue }`. Ten obiekt jest przechowywany przez Reacta, więc podczas następnego renderowania zostanie zwrócony ten sam obiekt. Zauważ, że w tym przykładzie funkcja ustawiająca stan nie jest używana. Jest to zbędne, ponieważ `useRef` zawsze musi zwracać ten sam obiekt! -React provides a built-in version of `useRef` because it is common enough in practice. But you can think of it as a regular state variable without a setter. If you're familiar with object-oriented programming, refs might remind you of instance fields--but instead of `this.something` you write `somethingRef.current`. +React zapewnia wbudowaną wersję `useRef`, ponieważ jest to na tyle powszechne w praktyce. Możesz jednak traktować to jako zwykłą zmienną stanu bez funkcji ustawiającej. Jeśli znasz programowanie obiektowe, referencje mogą przypominać ci pola instancji, ale zamiast `this.something` napiszesz `somethingRef.current`. -## When to use refs {/*when-to-use-refs*/} +## Kiedy używać referencji {/*when-to-use-refs*/} -Typically, you will use a ref when your component needs to "step outside" React and communicate with external APIs—often a browser API that won't impact the appearance of the component. Here are a few of these rare situations: +Zwykle będziesz używać referencji, gdy twój komponent będzie musiał "wyjść poza" React i komunikować się z zewnętrznymi API, często z API przeglądarki, które nie wpływa na wygląd komponentu. Oto kilka rzadkich przypadków użycia: -- Storing [timeout IDs](https://developer.mozilla.org/docs/Web/API/setTimeout) -- Storing and manipulating [DOM elements](https://developer.mozilla.org/docs/Web/API/Element), which we cover on [the next page](/learn/manipulating-the-dom-with-refs) -- Storing other objects that aren't necessary to calculate the JSX. +- Przechowywanie [identyfikatorów timeoutów](https://developer.mozilla.org/docs/Web/API/setTimeout) +- Przechowywanie i manipulowanie [elementami DOM](https://developer.mozilla.org/docs/Web/API/Element), co omówimy na [następnej stronie](/learn/manipulating-the-dom-with-refs) +- Przechowywanie obiektów, które nie wpływają na obliczanie JSX. -If your component needs to store some value, but it doesn't impact the rendering logic, choose refs. +Jeśli twój komponent musi przechować wartość, która nie wpływa na logikę renderowania, użyj referencji. -## Best practices for refs {/*best-practices-for-refs*/} +## Najlepsze praktyki dotyczące referencji {/*best-practices-for-refs*/} -Following these principles will make your components more predictable: +Stosowanie się do tych zasad sprawi, że twoje komponenty będą bardziej przewidywalne: -- **Treat refs as an escape hatch.** Refs are useful when you work with external systems or browser APIs. If much of your application logic and data flow relies on refs, you might want to rethink your approach. -- **Don't read or write `ref.current` during rendering.** If some information is needed during rendering, use [state](/learn/state-a-components-memory) instead. Since React doesn't know when `ref.current` changes, even reading it while rendering makes your component's behavior difficult to predict. (The only exception to this is code like `if (!ref.current) ref.current = new Thing()` which only sets the ref once during the first render.) +- **Traktuj referencje jako wyjście awaryjne.** Referencje przydają się podczas pracy z systemami zewnętrznymi lub API przeglądarki. Jeśli większość logiki aplikacji i przepływu danych opiera się na referencjach, warto przemyśleć swoje podejście. +- **Nie odczytuj ani nie zapisuj `ref.current` podczas renderowania.** Jeśli jakaś informacja jest potrzebna podczas renderowania, użyj [stanu](/learn/state-a-components-memory). Ponieważ React nie wie, kiedy `ref.current` się zmienia, nawet odczytanie go podczas renderowania sprawia, że zachowanie komponentu staje się trudne do przewidzenia. (Jedynym wyjątkiem od tej zasady jest kod taki jak `if (!ref.current) ref.current = new Thing()`, który ustawia referencję tylko raz podczas pierwszego renderowania.) -Limitations of React state don't apply to refs. For example, state acts like a [snapshot for every render](/learn/state-as-a-snapshot) and [doesn't update synchronously.](/learn/queueing-a-series-of-state-updates) But when you mutate the current value of a ref, it changes immediately: +Ograniczenia stanu w React nie dotyczą referencji. Na przykład, stan działa jak [migawka dla każdego renderowania](/learn/state-as-a-snapshot) i nie [aktualizuje się synchronicznie.](/learn/queueing-a-series-of-state-updates) Jednak gdy zmieniasz bieżącą wartość referencji, zmiana następuje natychmiastowo: ```js ref.current = 5; console.log(ref.current); // 5 ``` -This is because **the ref itself is a regular JavaScript object,** and so it behaves like one. +Dzieje się tak, ponieważ **referencja sama w sobie jest zwykłym obiektem JavaScript**, więc tak też się zachowuje. -You also don't need to worry about [avoiding mutation](/learn/updating-objects-in-state) when you work with a ref. As long as the object you're mutating isn't used for rendering, React doesn't care what you do with the ref or its contents. +Nie musisz również martwić się o [unikanie mutacji](/learn/updating-objects-in-state) podczas pracy z referencją. Dopóki obiekt, który mutujesz, nie jest używany do renderowania, React nie interesuje się tym, co robisz z referencją lub jej zawartością. -## Refs and the DOM {/*refs-and-the-dom*/} +## Referencje i DOM {/*refs-and-the-dom*/} -You can point a ref to any value. However, the most common use case for a ref is to access a DOM element. For example, this is handy if you want to focus an input programmatically. When you pass a ref to a `ref` attribute in JSX, like `
`, React will put the corresponding DOM element into `myRef.current`. Once the element is removed from the DOM, React will update `myRef.current` to be `null`. You can read more about this in [Manipulating the DOM with Refs.](/learn/manipulating-the-dom-with-refs) +Referencję możesz przypisać do dowolnej wartości. Jednak najczęstszym przypadkiem użycia referencji jest dostęp do elementu DOM. Jest to na przykład przydatne, jeśli chcesz programowo ustawić fokus na polu wejściowym. Jeśli przekażesz referencję do atrybutu `ref` w JSX, jak na przykład `
`, React umieści odpowiadający element DOM w `myRef.current`. Gdy element zostanie usunięty z DOM, React zaktualizuje `myRef.current`, ustawiając go na `null`. Możesz przeczytać więcej na ten temat w rozdziale [Manipulowanie DOM przy użyciu referencji](/learn/manipulating-the-dom-with-refs). -- Refs are an escape hatch to hold onto values that aren't used for rendering. You won't need them often. -- A ref is a plain JavaScript object with a single property called `current`, which you can read or set. -- You can ask React to give you a ref by calling the `useRef` Hook. -- Like state, refs let you retain information between re-renders of a component. -- Unlike state, setting the ref's `current` value does not trigger a re-render. -- Don't read or write `ref.current` during rendering. This makes your component hard to predict. +- Referencje to "wyjście awaryjne" do przechowywania wartości, które nie są używane do renderowania. Nie będziesz ich potrzebować zbyt często. +- Referencja to zwykły obiekt JavaScript z pojedynczą właściwością o nazwie `current`, którą możesz odczytać lub ustawić. +- Możesz uzyskać referencję od Reacta, wywołując hook `useRef`. +- Podobnie jak stan, referencje pozwalają przechowywać informacje między przerenderowaniami komponentu. +- W przeciwieństwie do stanu, ustawienie wartości `current` referencji nie powoduje ponownego przerenderowania. +- Nie odczytuj ani nie zapisuj `ref.current` podczas renderowania. To sprawia, że działanie komponentu staje się trudne do przewidzenia. @@ -301,13 +301,13 @@ You can point a ref to any value. However, the most common use case for a ref is -#### Fix a broken chat input {/*fix-a-broken-chat-input*/} +#### Napraw uszkodzone pole wprowadzania czatu {/*fix-a-broken-chat-input*/} -Type a message and click "Send". You will notice there is a three second delay before you see the "Sent!" alert. During this delay, you can see an "Undo" button. Click it. This "Undo" button is supposed to stop the "Sent!" message from appearing. It does this by calling [`clearTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/clearTimeout) for the timeout ID saved during `handleSend`. However, even after "Undo" is clicked, the "Sent!" message still appears. Find why it doesn't work, and fix it. +Wpisz wiadomość i kliknij "Wyślij". Zauważysz, że pojawi się opóźnienie trzech sekund, zanim zobaczysz komunikat "Wysłano!". W tym czasie możesz zobaczyć przycisk "Cofnij". Kliknij go. Przycisk "Cofnij" ma zatrzymać wyświetlanie komunikatu "Wysłano!". Robi to poprzez wywołanie metody [`clearTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/clearTimeout) dla identyfikatora timeout zapisanego podczas `handleSend`. Jednak nawet po kliknięciu "Cofnij" komunikat "Wysłano!" nadal się pojawia. Znajdź przyczynę, dlaczego to nie działa, i napraw to. -Regular variables like `let timeoutID` don't "survive" between re-renders because every render runs your component (and initializes its variables) from scratch. Should you keep the timeout ID somewhere else? +Zwykłe zmienne, takie jak `let timeoutID`, nie "przetrwają" między przerenderowaniami, ponieważ każdy render uruchamia Twój komponent (i inicjalizuje jego zmienne) od nowa. Czy powinieneś przechować identyfikator timeoutu gdzie indziej? @@ -324,7 +324,7 @@ export default function Chat() { function handleSend() { setIsSending(true); timeoutID = setTimeout(() => { - alert('Sent!'); + alert('Wysłano!'); setIsSending(false); }, 3000); } @@ -344,11 +344,11 @@ export default function Chat() { {isSending && } @@ -360,7 +360,7 @@ export default function Chat() { -Whenever your component re-renders (such as when you set state), all local variables get initialized from scratch. This is why you can't save the timeout ID in a local variable like `timeoutID` and then expect another event handler to "see" it in the future. Instead, store it in a ref, which React will preserve between renders. +Kiedy Twój komponent jest renderowany ponownie (na przykład, gdy ustawisz stan), wszystkie zmienne lokalne są inicjalizowane od nowa. Dlatego nie możesz przechować identyfikatora timeoutu w zmiennej lokalnej, takiej jak `timeoutID`, i oczekiwać, że inna funkcja obsługująca zdarzenie "zobaczy" ją w przyszłości. Zamiast tego, przechowaj go w referencji, którą React zachowa między przerenderowaniami. @@ -375,7 +375,7 @@ export default function Chat() { function handleSend() { setIsSending(true); timeoutRef.current = setTimeout(() => { - alert('Sent!'); + alert('Wysłano!'); setIsSending(false); }, 3000); } @@ -395,11 +395,11 @@ export default function Chat() { {isSending && } @@ -412,9 +412,9 @@ export default function Chat() { -#### Fix a component failing to re-render {/*fix-a-component-failing-to-re-render*/} +#### Napraw komponent, który nie renderuje się ponownie {/*fix-a-component-failing-to-re-render*/} -This button is supposed to toggle between showing "On" and "Off". However, it always shows "Off". What is wrong with this code? Fix it. +Ten przycisk powinien przełączać się między wyświetlaniem "Włącz" a "Wyłącz". Jednak zawsze wyświetla "Wyłącz". Co jest nie tak w tym kodzie? Napraw go. @@ -428,7 +428,7 @@ export default function Toggle() { ); } @@ -438,7 +438,7 @@ export default function Toggle() { -In this example, the current value of a ref is used to calculate the rendering output: `{isOnRef.current ? 'On' : 'Off'}`. This is a sign that this information should not be in a ref, and should have instead been put in state. To fix it, remove the ref and use state instead: +W tym przykładzie bieżąca wartość referencji jest używana do obliczenia wyniku renderowania: `{isOnRef.current ? 'Włącz' : 'Wyłącz'}`. Oznacza to, że ta informacja nie powinna być przechowywana w referencji, ale powinna zostać umieszczona w stanie. Aby to naprawić, należy usunąć referencję i zamiast niej użyć stanu: @@ -452,7 +452,7 @@ export default function Toggle() { ); } @@ -462,17 +462,17 @@ export default function Toggle() { -#### Fix debouncing {/*fix-debouncing*/} +#### Napraw debouncing {/*fix-debouncing*/} -In this example, all button click handlers are ["debounced".](https://redd.one/blog/debounce-vs-throttle) To see what this means, press one of the buttons. Notice how the message appears a second later. If you press the button while waiting for the message, the timer will reset. So if you keep clicking the same button fast many times, the message won't appear until a second *after* you stop clicking. Debouncing lets you delay some action until the user "stops doing things". +W tym przykładzie wszystkie procedury obsługi kliknięć przycisków są ["debouncowane".](https://redd.one/blog/debounce-vs-throttle) Aby zobaczyć, co to oznacza, naciśnij jeden z przycisków. Zauważ, że komunikat pojawi się sekundę później. Jeśli naciśniesz przycisk podczas oczekiwania na komunikat, licznik zostanie zresetowany. Dlatego, jeśli będziesz szybko klikać ten sam przycisk wiele razy, komunikat nie pojawi się, dopóki nie przestaniesz klikać przez sekundę. Debouncing pozwala opóźnić wykonanie jakiejś akcji, dopóki użytkownik nie "przestanie robić rzeczy". -This example works, but not quite as intended. The buttons are not independent. To see the problem, click one of the buttons, and then immediately click another button. You'd expect that after a delay, you would see both button's messages. But only the last button's message shows up. The first button's message gets lost. +Ten przykład działa, ale nie do końca zgodnie z zamierzeniami. Przyciski są niezależne. Aby zobaczyć problem, kliknij jeden z przycisków, a następnie natychmiast kliknij inny przycisk. Można się spodziewać, że po opóźnieniu pojawią się komunikaty obu przycisków. Pojawia się jednak tylko komunikat ostatniego przycisku. Wiadomość pierwszego przycisku zostaje utracona. -Why are the buttons interfering with each other? Find and fix the issue. +Dlaczego przyciski przeszkadzają sobie nawzajem? Znajdź i rozwiąż problem. -The last timeout ID variable is shared between all `DebouncedButton` components. This is why clicking one button resets another button's timeout. Can you store a separate timeout ID for each button? +Ostatnia zmienna timeout ID jest współdzielona pomiędzy wszystkimi komponentami `DebouncedButton`. Dlatego kliknięcie jednego przycisku resetuje timeout innego przycisku. Czy można przechowywać osobne timeout ID dla każdego przycisku? @@ -498,19 +498,19 @@ export default function Dashboard() { return ( <> alert('Spaceship launched!')} + onClick={() => alert('Statek kosmiczny wystartował!')} > - Launch the spaceship + Wystartuj statek kosmiczny alert('Soup boiled!')} + onClick={() => alert('Zupa się ugotowała!')} > - Boil the soup + Ugotuj zupę alert('Lullaby sung!')} + onClick={() => alert('Kołysanka zaśpiewana!')} > - Sing a lullaby + Zaśpiewaj kołysankę ) @@ -525,7 +525,7 @@ button { display: block; margin: 10px; } -A variable like `timeoutID` is shared between all components. This is why clicking on the second button resets the first button's pending timeout. To fix this, you can keep timeout in a ref. Each button will get its own ref, so they won't conflict with each other. Notice how clicking two buttons fast will show both messages. +Zmienna taka jak `timeoutID` jest współdzielona między wszystkimi komponentami. Dlatego kliknięcie drugiego przycisku resetuje oczekujący timeout pierwszego przycisku. Aby to naprawić, można przechować timeout w referencji. Każdy przycisk będzie miał swoją własną referencję, dzięki czemu nie będą one ze sobą kolidować. Zauważ, że szybkie kliknięcie dwóch przycisków spowoduje wyświetlenie obu komunikatów. @@ -550,19 +550,19 @@ export default function Dashboard() { return ( <> alert('Spaceship launched!')} + onClick={() => alert('Statek kosmiczny wystartował!')} > - Launch the spaceship + Wystartuj statek kosmiczny alert('Soup boiled!')} + onClick={() => alert('Zupa się ugotowała!')} > - Boil the soup + Ugotuj zupę alert('Lullaby sung!')} + onClick={() => alert('Kołysanka zaśpiewana!')} > - Sing a lullaby + Zaśpiewaj kołysankę ) @@ -577,11 +577,11 @@ button { display: block; margin: 10px; } -#### Read the latest state {/*read-the-latest-state*/} +#### Odczytaj najnowszą wartość stanu {/*read-the-latest-state*/} -In this example, after you press "Send", there is a small delay before the message is shown. Type "hello", press Send, and then quickly edit the input again. Despite your edits, the alert would still show "hello" (which was the value of state [at the time](/learn/state-as-a-snapshot#state-over-time) the button was clicked). +W tym przykładzie, po naciśnięciu przycisku "Wyślij", występuje niewielkie opóźnienie przed wyświetleniem wiadomości. Wpisz "Cześć", naciśnij Wyślij, a następnie szybko edytuj dane wejściowe ponownie. Pomimo edycji, alert nadal będzie pokazywał "Cześć" (które było wartością stanu w [momencie](/learn/state-as-a-snapshot#state-over-time), kiedy przycisk został kliknięty). -Usually, this behavior is what you want in an app. However, there may be occasional cases where you want some asynchronous code to read the *latest* version of some state. Can you think of a way to make the alert show the *current* input text rather than what it was at the time of the click? +Zazwyczaj takie zachowanie jest pożądane w aplikacji. Mogą jednak wystąpić sporadyczne przypadki, w których chcesz, aby jakiś asynchroniczny kod odczytał *najnowszą* wersję jakiegoś stanu. Czy potrafisz wymyślić sposób, aby alert pokazywał *aktualny* tekst wprowadzony w polu, a nie to, który był w momencie kliknięcia? @@ -593,7 +593,7 @@ export default function Chat() { function handleSend() { setTimeout(() => { - alert('Sending: ' + text); + alert('Wysyłanie: ' + text); }, 3000); } @@ -605,7 +605,7 @@ export default function Chat() { /> ); @@ -616,7 +616,8 @@ export default function Chat() { -State works [like a snapshot](/learn/state-as-a-snapshot), so you can't read the latest state from an asynchronous operation like a timeout. However, you can keep the latest input text in a ref. A ref is mutable, so you can read the `current` property at any time. Since the current text is also used for rendering, in this example, you will need *both* a state variable (for rendering), *and* a ref (to read it in the timeout). You will need to update the current ref value manually. +Stan działa [jak migawka](/learn/state-as-a-snapshot), więc nie można odczytać najnowszego stanu z operacji asynchronicznej, takiej jak np. timeout. Można jednak przechowywać najnowszy tekst wejściowy w referencji. Referencja jest mutowalna, więc można odczytać właściwość `current` w dowolnym momencie. Ponieważ bieżący tekst jest również używany do renderowania, w tym przykładzie będziesz potrzebował *zarówno* zmiennej stanu (do renderowania), *i* ref (aby odczytać go w timeoucie). Będziesz musiał ręcznie zaktualizować bieżącą wartość referencji. + @@ -634,7 +635,7 @@ export default function Chat() { function handleSend() { setTimeout(() => { - alert('Sending: ' + textRef.current); + alert('Wysyłanie: ' + textRef.current); }, 3000); } @@ -646,7 +647,7 @@ export default function Chat() { /> ); diff --git a/src/sidebarLearn.json b/src/sidebarLearn.json index 3516b19a0..8a78371af 100644 --- a/src/sidebarLearn.json +++ b/src/sidebarLearn.json @@ -174,7 +174,7 @@ "tags": ["advanced"], "routes": [ { - "title": "Referencing Values with Refs", + "title": "Odwoływanie się do wartości za pomocą referencji", "path": "/learn/referencing-values-with-refs" }, { From 3af82339f925fb8d70f1af9b8862a7042b013afe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Paj=C4=85k?= Date: Wed, 2 Apr 2025 20:06:45 +0200 Subject: [PATCH 2/2] refactor: apply review feedback --- .../learn/referencing-values-with-refs.md | 82 +++++++++---------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/src/content/learn/referencing-values-with-refs.md b/src/content/learn/referencing-values-with-refs.md index f72d5ef9b..6836359d6 100644 --- a/src/content/learn/referencing-values-with-refs.md +++ b/src/content/learn/referencing-values-with-refs.md @@ -4,7 +4,7 @@ title: 'Odwoływanie się do wartości za pomocą referencji' -Gdy chcesz, aby komponent "zapamiętał" pewne informacje, ale nie chcesz, aby te informacje [wywoływały ponowne renderowania](/learn/render-and-commit), możesz użyć *referencji*. +Gdy chcesz, aby komponent "zapamiętał" pewne informacje, ale nie chcesz, aby te informacje [wywoływały ponowne renderowania](/learn/render-and-commit), możesz użyć *referencji* (ang. _reference_, w skrócie _ref_). @@ -25,7 +25,7 @@ Możesz dodać referencję do swojego komponentu, importując hook `useRef` z Re import { useRef } from 'react'; ``` -We wnętrzu swojego komponentu wywołaj hook `useRef`, przekazując jako jedyny argument początkową wartość, do której chcesz się odwoływać. Na przykład, oto referencja do wartości `0`: +We wnętrzu swojego komponentu wywołaj hook `useRef`, przekazując jako jedyny argument wartość początkową, do której chcesz się odwoływać. Na przykład, oto referencja do wartości `0`: ```js const ref = useRef(0); @@ -35,13 +35,13 @@ const ref = useRef(0); ```js { - current: 0 // Wartość, którą przekazałeś do useRef + current: 0 // Wartość, którą przekazano do useRef } ``` -Możesz uzyskać dostęp do bieżącej wartości tej referencji przez właściwość `ref.current`. Ta wartość jest celowo mutowalna, co oznacza, że możesz zarówno ją odczytywać, jak i zapisywać. To jak tajna kieszeń twojego komponentu, której React nie śledzi. (To właśnie sprawia, że jest to "wyjście awaryjne" z jednokierunkowego przepływu danych Reacta - więcej na ten temat poniżej!) +Możesz uzyskać dostęp do bieżącej wartości tej referencji przez właściwość `ref.current`. Ta wartość jest celowo mutowalna (ang. _mutable_), co oznacza, że możesz ją zarówno odczytywać, jak i zapisywać. To jak taka ukryta kieszeń twojego komponentu, której React nie śledzi. To właśnie sprawia, że jest to "ukryta furtka" pozwalająca wyjść poza jednokierunkowy przepływ danych w Reakcie - więcej na ten temat poniżej! Tutaj, przycisk będzie inkrementować `ref.current` przy każdym kliknięciu: @@ -55,7 +55,7 @@ export default function Counter() { function handleClick() { ref.current = ref.current + 1; - alert('Kliknąłeś ' + ref.current + ' razy!'); + alert('Kliknięto ' + ref.current + ' razy!'); } return ( @@ -68,13 +68,13 @@ export default function Counter() { -Referencja wskazuje na liczbę, ale podobnie jak [stan](/learn/state-a-components-memory), możesz wskazać na cokolwiek: ciąg znaków, obiekt, a nawet funkcję. W przeciwieństwie do stanu, referencja to zwykły obiekt JavaScript z właściwością `current`, którą możesz odczytać i modyfikować. +Referencja wskazuje na liczbę, ale podobnie jak [stan](/learn/state-a-components-memory), możesz wskazać na cokolwiek: ciąg znaków, obiekt, a nawet funkcję. W przeciwieństwie do stanu, referencja to zwykły obiekt javascriptowy z właściwością `current`, którą możesz odczytać i modyfikować. Zwróć uwagę, że **komponent nie renderuje się ponownie przy każdej inkrementacji.** Podobnie jak stan, referencje są przechowywane przez Reacta między przerenderowaniami. Jednak ustawienie stanu powoduje ponowne renderowanie komponentu, a zmiana referencji - nie! -## Przykład: budowanie stoperu {/*example-building-a-stopwatch*/} +## Przykład: budowanie stopera {/*example-building-a-stopwatch*/} -Możesz połączyć referencje i stan w jednym komponencie. Na przykład, zbudujmy stoper, który użytkownik może uruchomić lub zatrzymać, naciskając przycisk. Aby wyświetlić, ile czasu minęło od momentu naciśnięcia przycisku "Start", musisz śledzić, kiedy przycisk Start został naciśnięty i jaki jest bieżący czas. **Te informacje są używane do renderowania, dlatego będziesz przechowywać je w stanie:** +Możesz połączyć referencje i stan w jednym komponencie. Na przykład zbudujmy stoper, który użytkownik może uruchomić lub zatrzymać, naciskając przycisk. Aby wyświetlić, ile czasu minęło od momentu naciśnięcia przycisku "Start", musisz śledzić, kiedy przycisk Start został naciśnięty i jaki jest bieżący czas. **Te informacje są używane do renderowania, dlatego będziesz przechowywać je w stanie:** ```js const [startTime, setStartTime] = useState(null); @@ -121,7 +121,7 @@ export default function Stopwatch() { -Kiedy przycisk "Stop" zostanie naciśnięty, musisz anulować istniejący interwał, aby przestał aktualizować zmienną stanu now. Możesz to zrobić, wywołując metodę [`clearInterval`](https://developer.mozilla.org/en-US/docs/Web/API/clearInterval), ale musisz przekazać mu identyfikator interwału, który został wcześniej zwrócony przez wywołanie metody `setInterval` po naciśnięciu przycisku Start. Musisz przechować identyfikator interwału w jakimś miejscu. **Ponieważ identyfikator interwału nie jest używany do renderowania, możesz przechować go w referencji:** +Kiedy przycisk "Stop" zostanie naciśnięty, musisz anulować istniejący interwał, aby przestał aktualizować zmienną stanu `now`. Możesz to zrobić, wywołując metodę [`clearInterval`](https://developer.mozilla.org/en-US/docs/Web/API/clearInterval), ale musisz przekazać mu identyfikator interwału, który został wcześniej zwrócony przez wywołanie metody `setInterval` po naciśnięciu przycisku Start. Musisz przechować identyfikator interwału w jakimś miejscu. **Ponieważ identyfikator interwału nie jest używany do renderowania, możesz przechować go w referencji:** @@ -168,18 +168,18 @@ export default function Stopwatch() { -Jeśli dana informacja jest wykorzystywana podczas renderowania, przechowuj ją w stanie. Kiedy informacja jest potrzebna tylko przez obsługiwacze zdarzeń i jej zmiana nie wymaga ponownego renderowania, użycie referencji może być bardziej wydajne. +Jeśli dana informacja jest wykorzystywana podczas renderowania, przechowuj ją w stanie. Kiedy informacja jest potrzebna tylko dla procedur obsługi zdarzeń i jej zmiana nie wymaga ponownego renderowania, użycie referencji może być bardziej wydajne. ## Różnice między referencjami a stanem {/*differences-between-refs-and-state*/} -Możesz pomyśleć, że referencje wydają się mniej "rygorystyczne" niż stan – na przykład pozwalają na mutowanie wartości bez konieczności używania funkcji do ustawiania stanu. Jednak w większości przypadków będziesz chciał używać stanu. Referencje to "wyjście awaryjne", które rzadko będziesz wykorzystywać. Oto porównanie stanu i referencji: +Możesz pomyśleć, że referencje wydają się mniej "rygorystyczne" niż stan – na przykład pozwalają na mutowanie wartości bez konieczności używania funkcji do ustawiania stanu. Jednak w większości przypadków będziesz chcieć używać stanu. Referencje to "ukryte furtki", które rzadko będziesz wykorzystywać. Oto porównanie stanu i referencji: | refs | state | |---------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------| | `useRef(initialValue)` zwraca `{ current: initialValue }` | `useState(initialValue)` zwraca bieżącą wartość zmiennej stanu oraz funkcję ustawiającą stan (`[value, setValue]`) | -| Nie wywołuje ponownego renderowania, gdy go zmienisz. | Wywołuje ponowne renderowanie, gdy go zmienisz. | -| "Mutowalny" - możesz modyfikować i aktualizować wartość current poza procesem renderowania. | "Niemutowalny" - musisz używać funkcji ustawiającej stan, aby modyfikować zmienne stanu i zainicjować kolejne renderowanie. | -| Nie powinieneś odczytywać (ani zapisywać) wartości `current` podczas renderowania. | Możesz odczytać stan w dowolnym momencie. Jednak każde renderowanie ma swoją własną [migawkę](/learn/state-as-a-snapshot) stanu, która nie zmienia się. | +| Nie wywołuje ponownego renderowania, gdy ją zmienisz. | Wywołuje ponowne renderowanie, gdy go zmienisz. | +| Mutowalny - możesz modyfikować i aktualizować wartość `current` poza procesem renderowania. | Niemutowalny - musisz używać funkcji ustawiającej stan, aby modyfikować zmienne stanu i zainicjować kolejne renderowanie. | +| Nie powinno się odczytywać (ani zapisywać) wartości `current` podczas renderowania. | Możesz odczytać stan w dowolnym momencie. Jednak każde renderowanie ma swoją własną [migawkę](/learn/state-as-a-snapshot) stanu, która nie zmienia się. | Oto przycisk licznika zaimplementowany za pomocą stanu: @@ -197,7 +197,7 @@ export default function Counter() { return ( ); } @@ -207,7 +207,7 @@ export default function Counter() { Ponieważ wartość `count` jest wyświetlana, ma sens użycie zmiennej stanu do jej przechowywania. Kiedy wartość licznika jest ustawiana za pomocą `setCount()`, React ponownie renderuje komponent, a ekran jest aktualizowany, aby odzwierciedlić nową wartość licznika. -Gdybyś próbował zaimplementować to za pomocą referencji, React nigdy nie przerenderowałby ponownie komponentu, więc nigdy nie zobaczyłbyś zmiany licznika! Zobacz, że kliknięcie tego przycisku **nie aktualizuje jego tekstu**: +Gdyby spróbować zaimplementować to za pomocą referencji, React nigdy nie przerenderowałby ponownie komponentu, więc zmiana licznika nie byłaby nigdy widoczna! Zauważ, że kliknięcie tego przycisku **nie aktualizuje jego tekstu**: @@ -224,7 +224,7 @@ export default function Counter() { return ( ); } @@ -236,9 +236,9 @@ Dlatego odczytywanie `ref.current` podczas renderowania prowadzi do niepewnego k -#### Jak działa useRef wewnątrz?? {/*how-does-use-ref-work-inside*/} +#### Jak działa useRef wewnątrz? {/*how-does-use-ref-work-inside*/} -Chociaż zarówno `useState`, jak i `useRef` są udostępniane przez React, w zasadzie `useRef` mogłoby być zaimplementowane na bazie `useState`. Możesz sobie wyobrazić, że wewnątrz Reacta, `useRef` jest zaimplementowane w ten sposób: +Chociaż zarówno `useState`, jak i `useRef` są udostępniane przez Reacta, w zasadzie `useRef` mogłoby być zaimplementowane na bazie `useState`. Możesz sobie wyobrazić, że wewnątrz Reacta, `useRef` jest zaimplementowane w ten sposób: ```js // Wewnątrz Reacta @@ -250,17 +250,17 @@ function useRef(initialValue) { Podczas pierwszego renderowania, `useRef` zwraca `{ current: initialValue }`. Ten obiekt jest przechowywany przez Reacta, więc podczas następnego renderowania zostanie zwrócony ten sam obiekt. Zauważ, że w tym przykładzie funkcja ustawiająca stan nie jest używana. Jest to zbędne, ponieważ `useRef` zawsze musi zwracać ten sam obiekt! -React zapewnia wbudowaną wersję `useRef`, ponieważ jest to na tyle powszechne w praktyce. Możesz jednak traktować to jako zwykłą zmienną stanu bez funkcji ustawiającej. Jeśli znasz programowanie obiektowe, referencje mogą przypominać ci pola instancji, ale zamiast `this.something` napiszesz `somethingRef.current`. +React zapewnia wbudowaną wersję `useRef`, ponieważ jest to na tyle powszechne w użyciu. Możesz jednak traktować to jako zwykłą zmienną stanu bez funkcji ustawiającej. Jeśli znasz programowanie obiektowe, referencje mogą przypominać ci pola instancji, ale zamiast `this.something` napiszesz `somethingRef.current`. ## Kiedy używać referencji {/*when-to-use-refs*/} -Zwykle będziesz używać referencji, gdy twój komponent będzie musiał "wyjść poza" React i komunikować się z zewnętrznymi API, często z API przeglądarki, które nie wpływa na wygląd komponentu. Oto kilka rzadkich przypadków użycia: +Zwykle będziesz używać referencji, gdy twój komponent będzie musiał "wyjść poza" Reacta i komunikować się z zewnętrznymi API, najczęściej z API przeglądarki, które nie wpływa na wygląd komponentu. Oto kilka tych rzadkich przypadków użycia: - Przechowywanie [identyfikatorów timeoutów](https://developer.mozilla.org/docs/Web/API/setTimeout) - Przechowywanie i manipulowanie [elementami DOM](https://developer.mozilla.org/docs/Web/API/Element), co omówimy na [następnej stronie](/learn/manipulating-the-dom-with-refs) -- Przechowywanie obiektów, które nie wpływają na obliczanie JSX. +- Przechowywanie obiektów, które nie wpływają na obliczanie JSXa. Jeśli twój komponent musi przechować wartość, która nie wpływa na logikę renderowania, użyj referencji. @@ -268,31 +268,31 @@ Jeśli twój komponent musi przechować wartość, która nie wpływa na logikę Stosowanie się do tych zasad sprawi, że twoje komponenty będą bardziej przewidywalne: -- **Traktuj referencje jako wyjście awaryjne.** Referencje przydają się podczas pracy z systemami zewnętrznymi lub API przeglądarki. Jeśli większość logiki aplikacji i przepływu danych opiera się na referencjach, warto przemyśleć swoje podejście. -- **Nie odczytuj ani nie zapisuj `ref.current` podczas renderowania.** Jeśli jakaś informacja jest potrzebna podczas renderowania, użyj [stanu](/learn/state-a-components-memory). Ponieważ React nie wie, kiedy `ref.current` się zmienia, nawet odczytanie go podczas renderowania sprawia, że zachowanie komponentu staje się trudne do przewidzenia. (Jedynym wyjątkiem od tej zasady jest kod taki jak `if (!ref.current) ref.current = new Thing()`, który ustawia referencję tylko raz podczas pierwszego renderowania.) +- **Traktuj referencje jako ukrytą furtkę.** Referencje przydają się podczas pracy z systemami zewnętrznymi lub API przeglądarki. Jeśli większość logiki aplikacji i przepływu danych opiera się na referencjach, warto przemyśleć swoje podejście. +- **Nie odczytuj ani nie zapisuj `ref.current` podczas renderowania.** Jeśli jakaś informacja jest potrzebna podczas renderowania, użyj [stanu](/learn/state-a-components-memory). Ponieważ React nie wie, kiedy `ref.current` się zmienia, nawet odczytanie go podczas renderowania sprawia, że zachowanie komponentu staje się trudne do przewidzenia. Jedynym wyjątkiem od tej zasady jest kod taki jak `if (!ref.current) ref.current = new Thing()`, który ustawia referencję tylko raz podczas pierwszego renderowania. -Ograniczenia stanu w React nie dotyczą referencji. Na przykład, stan działa jak [migawka dla każdego renderowania](/learn/state-as-a-snapshot) i nie [aktualizuje się synchronicznie.](/learn/queueing-a-series-of-state-updates) Jednak gdy zmieniasz bieżącą wartość referencji, zmiana następuje natychmiastowo: +Ograniczenia stanu w Reakcie nie dotyczą referencji. Na przykład, stan działa jak [migawka dla każdego renderowania](/learn/state-as-a-snapshot) i [nie aktualizuje się synchronicznie.](/learn/queueing-a-series-of-state-updates) Jednak gdy zmieniasz bieżącą wartość referencji, zmiana następuje natychmiastowo: ```js ref.current = 5; console.log(ref.current); // 5 ``` -Dzieje się tak, ponieważ **referencja sama w sobie jest zwykłym obiektem JavaScript**, więc tak też się zachowuje. +Dzieje się tak, ponieważ **referencja sama w sobie jest zwykłym obiektem javascriptowym**, więc tak też się zachowuje. Nie musisz również martwić się o [unikanie mutacji](/learn/updating-objects-in-state) podczas pracy z referencją. Dopóki obiekt, który mutujesz, nie jest używany do renderowania, React nie interesuje się tym, co robisz z referencją lub jej zawartością. ## Referencje i DOM {/*refs-and-the-dom*/} -Referencję możesz przypisać do dowolnej wartości. Jednak najczęstszym przypadkiem użycia referencji jest dostęp do elementu DOM. Jest to na przykład przydatne, jeśli chcesz programowo ustawić fokus na polu wejściowym. Jeśli przekażesz referencję do atrybutu `ref` w JSX, jak na przykład `
`, React umieści odpowiadający element DOM w `myRef.current`. Gdy element zostanie usunięty z DOM, React zaktualizuje `myRef.current`, ustawiając go na `null`. Możesz przeczytać więcej na ten temat w rozdziale [Manipulowanie DOM przy użyciu referencji](/learn/manipulating-the-dom-with-refs). +Referencję możesz przypisać do dowolnej wartości. Jednak najczęstszym przypadkiem użycia referencji jest dostęp do elementu DOM. Jest to przydatne, jeśli na przykład chcesz programowo ustawić fokus na polu wejściowym. Jeśli przekażesz referencję do atrybutu `ref` w JSX, jak na przykład `
`, React umieści odpowiadający element DOM w `myRef.current`. Gdy element zostanie usunięty z DOM, React zaktualizuje `myRef.current`, ustawiając go na `null`. Możesz przeczytać więcej na ten temat w rozdziale [Manipulowanie DOM przy użyciu referencji](/learn/manipulating-the-dom-with-refs). -- Referencje to "wyjście awaryjne" do przechowywania wartości, które nie są używane do renderowania. Nie będziesz ich potrzebować zbyt często. -- Referencja to zwykły obiekt JavaScript z pojedynczą właściwością o nazwie `current`, którą możesz odczytać lub ustawić. +- Referencje to "ukryte furtki" do przechowywania wartości, które nie są używane do renderowania. Nie będziesz ich potrzebować zbyt często. +- Referencja to zwykły obiekt javascriptowy z pojedynczą właściwością o nazwie `current`, którą możesz odczytać lub ustawić. - Możesz uzyskać referencję od Reacta, wywołując hook `useRef`. -- Podobnie jak stan, referencje pozwalają przechowywać informacje między przerenderowaniami komponentu. -- W przeciwieństwie do stanu, ustawienie wartości `current` referencji nie powoduje ponownego przerenderowania. +- Podobnie jak stan, referencje pozwalają przechowywać informacje między ponownymi renderowaniami komponentu. +- W przeciwieństwie do stanu, ustawienie wartości `current` referencji nie powoduje ponownego renderowania. - Nie odczytuj ani nie zapisuj `ref.current` podczas renderowania. To sprawia, że działanie komponentu staje się trudne do przewidzenia. @@ -303,11 +303,11 @@ Referencję możesz przypisać do dowolnej wartości. Jednak najczęstszym przyp #### Napraw uszkodzone pole wprowadzania czatu {/*fix-a-broken-chat-input*/} -Wpisz wiadomość i kliknij "Wyślij". Zauważysz, że pojawi się opóźnienie trzech sekund, zanim zobaczysz komunikat "Wysłano!". W tym czasie możesz zobaczyć przycisk "Cofnij". Kliknij go. Przycisk "Cofnij" ma zatrzymać wyświetlanie komunikatu "Wysłano!". Robi to poprzez wywołanie metody [`clearTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/clearTimeout) dla identyfikatora timeout zapisanego podczas `handleSend`. Jednak nawet po kliknięciu "Cofnij" komunikat "Wysłano!" nadal się pojawia. Znajdź przyczynę, dlaczego to nie działa, i napraw to. +Wpisz wiadomość i kliknij "Wyślij". Zauważysz, że pojawi się opóźnienie trzech sekund, zanim zobaczysz komunikat "Wysłano!". W tym czasie możesz zobaczyć przycisk "Cofnij". Kliknij go. Przycisk "Cofnij" ma zatrzymać wyświetlanie komunikatu "Wysłano!". Robi to poprzez wywołanie metody [`clearTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/clearTimeout) dla identyfikatora timeout zapisanego podczas `handleSend`. Jednak nawet po kliknięciu "Cofnij" komunikat "Wysłano!" nadal się pojawia. Znajdź przyczynę, dlaczego to nie działa i napraw to. -Zwykłe zmienne, takie jak `let timeoutID`, nie "przetrwają" między przerenderowaniami, ponieważ każdy render uruchamia Twój komponent (i inicjalizuje jego zmienne) od nowa. Czy powinieneś przechować identyfikator timeoutu gdzie indziej? +Zwykłe zmienne, takie jak `let timeoutID`, nie "przetrwają" między ponownymi renderowaniami, ponieważ każde renderowanie uruchamia twój komponent (i inicjalizuje jego zmienne) od nowa. Czy nie powinno się przechować identyfikatora timeoutu gdzie indziej? @@ -360,7 +360,7 @@ export default function Chat() { -Kiedy Twój komponent jest renderowany ponownie (na przykład, gdy ustawisz stan), wszystkie zmienne lokalne są inicjalizowane od nowa. Dlatego nie możesz przechować identyfikatora timeoutu w zmiennej lokalnej, takiej jak `timeoutID`, i oczekiwać, że inna funkcja obsługująca zdarzenie "zobaczy" ją w przyszłości. Zamiast tego, przechowaj go w referencji, którą React zachowa między przerenderowaniami. +Kiedy twój komponent jest renderowany ponownie (na przykład, gdy ustawisz stan), wszystkie zmienne lokalne są inicjalizowane od nowa. Dlatego nie możesz przechować identyfikatora timeoutu w zmiennej lokalnej, takiej jak `timeoutID` i oczekiwać, że inna funkcja obsługująca zdarzenie "zobaczy" ją w przyszłości. Zamiast tego, przechowaj go w referencji, którą React zachowa między renderowaniami. @@ -464,15 +464,15 @@ export default function Toggle() { #### Napraw debouncing {/*fix-debouncing*/} -W tym przykładzie wszystkie procedury obsługi kliknięć przycisków są ["debouncowane".](https://redd.one/blog/debounce-vs-throttle) Aby zobaczyć, co to oznacza, naciśnij jeden z przycisków. Zauważ, że komunikat pojawi się sekundę później. Jeśli naciśniesz przycisk podczas oczekiwania na komunikat, licznik zostanie zresetowany. Dlatego, jeśli będziesz szybko klikać ten sam przycisk wiele razy, komunikat nie pojawi się, dopóki nie przestaniesz klikać przez sekundę. Debouncing pozwala opóźnić wykonanie jakiejś akcji, dopóki użytkownik nie "przestanie robić rzeczy". +W tym przykładzie wszystkie procedury obsługi kliknięć przycisków są ["debouncowane".](https://redd.one/blog/debounce-vs-throttle) Aby zobaczyć, co to oznacza, naciśnij jeden z przycisków. Zauważ, że komunikat pojawi się sekundę później. Jeśli naciśniesz przycisk podczas oczekiwania na komunikat, licznik zostanie zresetowany. Dlatego, jeśli będziesz szybko klikać ten sam przycisk wiele razy, komunikat nie pojawi się, dopóki nie przestaniesz klikać przez sekundę. Debouncing pozwala opóźnić wykonanie jakiejś akcji, dopóki użytkownik "nie przestanie robić rzeczy". -Ten przykład działa, ale nie do końca zgodnie z zamierzeniami. Przyciski są niezależne. Aby zobaczyć problem, kliknij jeden z przycisków, a następnie natychmiast kliknij inny przycisk. Można się spodziewać, że po opóźnieniu pojawią się komunikaty obu przycisków. Pojawia się jednak tylko komunikat ostatniego przycisku. Wiadomość pierwszego przycisku zostaje utracona. +Ten przykład działa, ale nie do końca zgodnie z założeniami. Przyciski nie są niezależne. Aby zobaczyć problem, kliknij jeden z przycisków, a następnie natychmiast kliknij inny przycisk. Można się spodziewać, że po opóźnieniu pojawią się komunikaty obu przycisków. Pojawia się jednak tylko komunikat ostatniego przycisku. Wiadomość pierwszego przycisku zostaje utracona. -Dlaczego przyciski przeszkadzają sobie nawzajem? Znajdź i rozwiąż problem. +Dlaczego przyciski zakłócają się nawzajem? Znajdź problem i go rozwiąż. -Ostatnia zmienna timeout ID jest współdzielona pomiędzy wszystkimi komponentami `DebouncedButton`. Dlatego kliknięcie jednego przycisku resetuje timeout innego przycisku. Czy można przechowywać osobne timeout ID dla każdego przycisku? +Ostatnia zmienna identyfikatora timeoutu jest współdzielona pomiędzy wszystkimi komponentami `DebouncedButton`. Dlatego kliknięcie jednego przycisku resetuje timeout innego przycisku. Czy można przechowywać osobne identyfikatory timeoutu dla każdego przycisku? @@ -579,9 +579,9 @@ button { display: block; margin: 10px; } #### Odczytaj najnowszą wartość stanu {/*read-the-latest-state*/} -W tym przykładzie, po naciśnięciu przycisku "Wyślij", występuje niewielkie opóźnienie przed wyświetleniem wiadomości. Wpisz "Cześć", naciśnij Wyślij, a następnie szybko edytuj dane wejściowe ponownie. Pomimo edycji, alert nadal będzie pokazywał "Cześć" (które było wartością stanu w [momencie](/learn/state-as-a-snapshot#state-over-time), kiedy przycisk został kliknięty). +W tym przykładzie, po naciśnięciu przycisku "Wyślij", występuje niewielkie opóźnienie przed wyświetleniem wiadomości. Wpisz "Cześć", naciśnij Wyślij, a następnie szybko edytuj dane wejściowe ponownie. Pomimo edycji, alert nadal będzie pokazywał "Cześć" (które było wartością stanu [w momencie](/learn/state-as-a-snapshot#state-over-time), kiedy przycisk został kliknięty). -Zazwyczaj takie zachowanie jest pożądane w aplikacji. Mogą jednak wystąpić sporadyczne przypadki, w których chcesz, aby jakiś asynchroniczny kod odczytał *najnowszą* wersję jakiegoś stanu. Czy potrafisz wymyślić sposób, aby alert pokazywał *aktualny* tekst wprowadzony w polu, a nie to, który był w momencie kliknięcia? +Zazwyczaj takie zachowanie jest pożądane w aplikacji. Mogą jednak wystąpić sporadyczne przypadki, w których chcesz, aby jakiś asynchroniczny kod odczytał *najnowszą* wersję jakiegoś stanu. Czy potrafisz wymyślić sposób, aby alert pokazywał *aktualny* tekst wprowadzony w polu, a nie ten, który był w momencie kliknięcia? @@ -616,7 +616,7 @@ export default function Chat() { -Stan działa [jak migawka](/learn/state-as-a-snapshot), więc nie można odczytać najnowszego stanu z operacji asynchronicznej, takiej jak np. timeout. Można jednak przechowywać najnowszy tekst wejściowy w referencji. Referencja jest mutowalna, więc można odczytać właściwość `current` w dowolnym momencie. Ponieważ bieżący tekst jest również używany do renderowania, w tym przykładzie będziesz potrzebował *zarówno* zmiennej stanu (do renderowania), *i* ref (aby odczytać go w timeoucie). Będziesz musiał ręcznie zaktualizować bieżącą wartość referencji. +Stan działa [jak migawka](/learn/state-as-a-snapshot), więc nie można odczytać najnowszego stanu z operacji asynchronicznej, takiej jak np. timeout. Można jednak przechowywać najnowszy tekst wejściowy w referencji. Referencja jest mutowalna, więc można odczytać właściwość `current` w dowolnym momencie. Ponieważ bieżący tekst jest również używany do renderowania, w tym przykładzie będziesz potrzebować *zarówno* zmiennej stanu (do renderowania) *oraz* referencji (aby odczytać go w timeoucie). Trzeba będzie ręcznie zaktualizować bieżącą wartość referencji.