You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When Webpack comes across this syntax, it automatically starts code-splitting
104
104
your app. If you're using Create React App, this is already configured for you
105
-
and you can [start using it](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md#code-splitting) immediately. It's also supported
105
+
and you can [start using it](https://facebook.github.io/create-react-app/docs/code-splitting) immediately. It's also supported
106
106
out of the box in [Next.js](https://github.com/zeit/next.js/#dynamic-import).
107
107
108
108
If you're setting up Webpack yourself, you'll probably want to read Webpack's
Copy file name to clipboardExpand all lines: content/tutorial/tutorial.md
+18-40Lines changed: 18 additions & 40 deletions
Original file line number
Diff line number
Diff line change
@@ -31,12 +31,8 @@ Samouczek podzieliliśmy na kilka części:
31
31
32
32
Nie musisz wcale przechodzić przez wszystkie części samouczka naraz, żeby wynieść z niego cokolwiek. Spróbuj jednak dojść najdalej jak możesz - nawet jeśli będą to tylko dwa rozdziały.
33
33
34
-
W trakcie wykonywania poleceń możesz kopiować kod do edytora, ale zalecamy pisanie go samodzielnie. Pozwoli ci to bardziej skupić się na poszczególnych zagadnieniach, dzięki czemu lepiej je sobie przyswoisz i zrozumiesz.
35
-
36
34
### Co będziemy budować? {#what-are-we-building}
37
35
38
-
W tym samouczku pokażemy, jak przy pomocy Reacta zbudować interaktywną grę w "kółko i krzyżyk".
39
-
40
36
Na koniec nasz kod będzie wyglądał tak: **[Efekt końcowy](https://codepen.io/gaearon/pen/gWWZgR?editors=0010)**. Być może w tej chwili kod wygląda bez sensu albo nie rozumiesz jego składni, ale bez obaw! Celem tego samouczka jest właśnie pomóc ci zrozumieć Reacta i jego składnię.
41
37
42
38
Zanim przystąpisz do dalszej lektury, zachęcamy cię do uruchomienia gry w "kółko i krzyżyk". Zwróć uwagę, że jedną z funkcjonalności tej aplikacji jest, znajdująca się na prawo od planszy, numerowana lista. Wyświetla ona na bieżąco wszystkie wykonywane w danej rozgrywce ruchy.
@@ -190,6 +186,8 @@ Komponent `Square` (pole) renderuje pojedynczy element `<button>`, a `Board` (pl
190
186
191
187
Na dobry początek, spróbujmy przekazać jakieś dane z komponentu `Board` do `Square`.
192
188
189
+
W trakcie wykonywania poleceń zalecamy pisanie kodu samodzielnie. Pozwoli ci to bardziej skupić się na poszczególnych zagadnieniach, dzięki czemu lepiej je sobie przyswoisz i zrozumiesz.
190
+
193
191
W metodzie `renderSquare` komponentu `Board` przekaż komponentowi `Square` atrybut o nazwie `value` (pol. *wartość*):
194
192
195
193
```js{3}
@@ -242,7 +240,7 @@ class Square extends React.Component {
242
240
}
243
241
```
244
242
245
-
Teraz gdy klikniemy na polu, przeglądarka wyświetli wiadomość w oknie dialogowym.
243
+
Teraz gdy klikniesz na polu, przeglądarka wyświetli wiadomość w oknie dialogowym.
246
244
247
245
>Uwaga
248
246
>
@@ -260,7 +258,7 @@ Teraz gdy klikniemy na polu, przeglądarka wyświetli wiadomość w oknie dialog
260
258
>}
261
259
>```
262
260
>
263
-
>Zauważ, że za pomocą `onClick={() => alert('kliknięto w przycisk')}` pod atrybutem `onClick` przekazujemy *funkcję*. Zostanie ona wywołana dopiero po kliknięciu w przycisk. Częstym błędem jest zapominanie o `() =>` i pisanie `onClick={alert('kliknięto w przycisk')}`, co powoduje wyświetlenie wiadomości w momencie renderowania komponentu.
261
+
>Zauważ, że za pomocą `onClick={() => alert('kliknięto w przycisk')}` pod atrybutem `onClick` przekazujemy *funkcję*. React wywoła ją dopiero po kliknięciu w przycisk. Częstym błędem jest zapominanie o `() =>` i pisanie `onClick={alert('kliknięto w przycisk')}`, co powoduje wyświetlenie wiadomości w momencie renderowania komponentu.
264
262
265
263
W następnym kroku sprawimy, by komponent `Square` "pamiętał", że został kliknięty, i wyświetlał literę "X". Komponenty mogą "pamiętać" o różnych rzeczach dzięki **stanowi** (ang. *state*).
266
264
@@ -294,7 +292,7 @@ class Square extends React.Component {
294
292
Teraz zmienimy kod w metodzie `render` komponentu `Square` tak, aby po kliknięciu wyświetlał wartość aktualnego stanu:
295
293
296
294
* zamień `this.props.value` na `this.state.value` wewnątrz znacznika `<button>`,
* umieść atrybuty `className` i `onClick` w osobnych liniach dla lepszej czytelności kodu.
299
297
300
298
Po wprowadzeniu powyższych zmian, element `<button>`, zwracany przez komponent `Square`, powinien wyglądać następująco:
@@ -356,7 +354,9 @@ Być może przeszło ci przez myśl, że to komponent `Board` powinien "pytać"
356
354
357
355
**Aby móc zebrać dane z wielu komponentów potomnych lub umożliwić dwóm potomkom komunikowanie się ze sobą, należy zadeklarować ich wspólny stan w rodzicu. Taki rodzic może wtedy przekazać poszczególne wartości potomkom poprzez atrybuty; dzięki temu potomkowie będą zsynchronizowani zarówno ze sobą nawzajem, jak i z rodzicem.**
358
356
359
-
Wynoszenie stanu w górę struktury to dość częsty zabieg podczas refaktoryzacji (ang. *refactoring*) kodu. Wykorzystajmy zatem okazję do wypróbowania tego schematu. Dodajmy konstruktor do komponentu `Board` i ustawmy w nim stan przechowujący tablicę dziewięciu wartości `null`. Każdy z elementów tej tablicy będzie odpowiadał jednemu polu na planszy:
357
+
Wynoszenie stanu w górę struktury to dość częsty zabieg podczas refaktoryzacji (ang. *refactoring*) kodu. Wykorzystajmy zatem okazję do wypróbowania tego schematu.
358
+
359
+
Dodaj konstruktor do komponentu `Board` i ustaw w nim stan przechowujący tablicę dziewięciu wartości `null`. Każdy z elementów tej tablicy będzie odpowiadał jednemu polu na planszy:
360
360
361
361
```javascript{2-7}
362
362
class Board extends React.Component {
@@ -370,35 +370,9 @@ class Board extends React.Component {
370
370
renderSquare(i) {
371
371
return <Square value={i} />;
372
372
}
373
-
374
-
render() {
375
-
const status = 'Następny gracz: X';
376
-
377
-
return (
378
-
<div>
379
-
<div className="status">{status}</div>
380
-
<div className="board-row">
381
-
{this.renderSquare(0)}
382
-
{this.renderSquare(1)}
383
-
{this.renderSquare(2)}
384
-
</div>
385
-
<div className="board-row">
386
-
{this.renderSquare(3)}
387
-
{this.renderSquare(4)}
388
-
{this.renderSquare(5)}
389
-
</div>
390
-
<div className="board-row">
391
-
{this.renderSquare(6)}
392
-
{this.renderSquare(7)}
393
-
{this.renderSquare(8)}
394
-
</div>
395
-
</div>
396
-
);
397
-
}
398
-
}
399
373
```
400
374
401
-
Gdy później wypełnimy planszę wartościami, tablica będzie wyglądała mniej więcej tak:
375
+
Gdy później wypełnimy planszę wartościami, tablica `this.state.squares`będzie wyglądała mniej więcej tak:
402
376
403
377
```javascript
404
378
[
@@ -432,7 +406,7 @@ Każde pole otrzyma poprzez atrybut `value` odpowiednio: `"X"`, `"O"` lub `null`
432
406
433
407
Następnie musimy zmienić zachowanie komponentu `Square` po kliknięciu na nim, ponieważ teraz to `Board` decyduje, które pola są wypełnione. Musimy zatem określić sposób, w jaki komponent `Square` może aktualizować stan swojego rodzica. Jako że stan komponentu `Board` należy tylko do niego, nie możemy tak po prostu nadpisać jego wartości z poziomu potomka `Square`.
434
408
435
-
Aby zapewnić komponentowi `Board` wyłączność na własność jego stanu, do komponentu `Square` przekażemy odpowiednią funkcję za pomocą atrybutów. Funkcja ta będzie wywoływana za każdym razem, gdy ktoś kliknie na pole. Zmieńmy więc metodę `renderSquare` w następujący sposób:
409
+
Zamiast tego, do komponentu `Square` przekażemy odpowiednią funkcję za pomocą atrybutów i sprawimy, by `Square` wywoływał ją za każdym razem, gdy ktoś kliknie na pole. Zmieńmy więc metodę `renderSquare` w następujący sposób:
436
410
437
411
```javascript{5}
438
412
renderSquare(i) {
@@ -478,11 +452,11 @@ Gdy użytkownik kliknie na pole, zostanie wywołana funkcja `onClick` dostarczon
478
452
2. Gdy użytkownik kliknie na przycisk, React wywoła procedurę obsługi zdarzenia `onClick` zdefiniowaną w metodzie `render()` komponentu `Square`.
479
453
3. Procedura ta wywoła funkcję `this.props.onClick()`, czyli atrybut przekazany przez komponent `Board`.
480
454
4. Ponieważ komponent `Board` przekazał swojemu potomkowi atrybut `onClick={() => this.handleClick(i)}`, kliknięcie w `Square` spowoduje w konsekwencji wywołanie `this.handleClick(i)` wewnątrz komponentu `Board`.
481
-
5. Nie zdefiniowaliśmy jeszcze metody `handleClick()`, dlatego aplikacja w tym momencie przestanie działać.
455
+
5. Nie zdefiniowaliśmy jeszcze metody `handleClick()`, dlatego aplikacja w tym momencie przestanie działać. Jeśli klikniesz na dowolne pole, zobaczysz błąd na czerwonym tle, mówiący coś w stylu: "this.handleClick is not a function" (pol. *this.handleClick nie jest funkcją*).
482
456
483
457
>Uwaga
484
458
>
485
-
>Atrybut `onClick` elementu DOM `<button>` ma dla Reacta specjalne znaczenie, ponieważ jest to wbudowany komponent. W przypadku własny komponentów, jak `Square`, nazwa tego atrybutu może być dowolna. Moglibyśmy nazwać inaczej zarówno atrybut `onClick` w `Square`, jak i `handleClick` w `Board`. Przyjęło się jednak określać atrybuty odpowiedzialne za wywołanie zdarzenia jako `on[Event]`, a procedury obsługi zdarzeń jako `handle[Event]`.
459
+
>Atrybut `onClick` elementu DOM `<button>` ma dla Reacta specjalne znaczenie, ponieważ jest to wbudowany komponent. W przypadku własny komponentów, jak `Square`, nazwa tego atrybutu może być dowolna. Moglibyśmy nazwać inaczej zarówno atrybut `onClick` w `Square`, jak i `handleClick` w `Board`, a kod nadal działałby w taki sam sposób. Przyjęło się jednak określać atrybuty odpowiedzialne za wywołanie zdarzenia jako `on[Event]`, a procedury obsługi zdarzeń jako `handle[Event]`.
486
460
487
461
Jeśli teraz klikniemy na polę planszy, otrzymamy błąd, ponieważ nie zdefiniowaliśmy jeszcze metody `handleClick`. Dodajmy ją zatem:
488
462
@@ -643,7 +617,9 @@ Za każdym razem, gdy użytkownik wykona ruch, zmienna `xIsNext` (typu zerojedyn
643
617
}
644
618
```
645
619
646
-
Po tej modyfikacji "krzyżyki" i "kółka" będą wykonywać ruchy na zmianę. Zaktualizujmy teraz wartość `status` w metodzie `render`, aby poprawnie wyświetlała, który gracz jest następny:
620
+
Po tej modyfikacji "krzyżyki" i "kółka" będą wykonywać ruchy na zmianę. Spróbuj zagrać!
621
+
622
+
Zaktualizujmy teraz wartość `status` w metodzie `render`, aby poprawnie wyświetlała, który gracz jest następny:
647
623
648
624
```javascript{2}
649
625
render() {
@@ -714,7 +690,7 @@ class Board extends React.Component {
714
690
715
691
### Ogłaszanie zwycięzcy {#declaring-a-winner}
716
692
717
-
Teraz gdy już wyświetlamy, który z graczy będzie wykonywał następny ruch, powinniśmy również ogłaszać zwycięzcę lub wyświetlać informację o braku możliwych ruchów. Do wyłaniania zwycięzcy posłuży nam następujące funkcja pomocnicza, którą należy dodać na końcu pliku:
693
+
Teraz gdy już wyświetlamy, który z graczy będzie wykonywał następny ruch, powinniśmy również ogłaszać zwycięzcę lub wyświetlać informację o braku możliwych ruchów. Do wyłaniania zwycięzcy posłuży nam następująca funkcja pomocnicza, którą należy dodać na końcu pliku:
718
694
719
695
```javascript
720
696
functioncalculateWinner(squares) {
@@ -738,6 +714,8 @@ function calculateWinner(squares) {
738
714
}
739
715
```
740
716
717
+
Dla dowolnej tablicy z dziewięcioma polami sprawdzi ona, który z graczy wygrał, a następnie zwróci odpowiednio: `'X'`, `'O'` lub `null`.
718
+
741
719
Funkcję `calculateWinner(squares)` wywołamy w metodzie `render` komponentu `Board`, sprawdzając w ten sposób, czy gracz aktualnie wykonujący ruch jest zwycięzcą. Jeśli odpowiedź będzie pozytywna, możemy wyświetlić tekst w stylu "Wygrywa: X" lub "Wygrywa: O". Podmieńmy `status` w metodzie `render` na:
0 commit comments