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
Copy file name to clipboardExpand all lines: src/content/6/fi/osa6c.md
+25-26Lines changed: 25 additions & 26 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@ lang: fi
7
7
8
8
<divclass="content">
9
9
10
-
Laajennetaan sovellusta siten, että muistiinpanot talletetaan backendiin. Käytetään osasta 2 tuttua [json-serveriä](/osa2/palvelimella_olevan_datan_hakeminen).
10
+
Laajennetaan sovellusta siten, että muistiinpanot talletetaan backendiin. Käytetään osasta 2 tuttua [JSON Serveriä](/osa2/palvelimella_olevan_datan_hakeminen).
11
11
12
12
Tallennetaan projektin juuren tiedostoon <i>db.json</i> tietokannan alkutila:
Monen actionin dispatchaaminen vaikuttaa hieman epäkäytännölliseltä. Lisätään action creatori <em>setNotes</em>, jonka avulla muistiinpanojen taulukon voi suoraan korvata. Saamme <em>createSlice</em>-funktion avulla haluamamme action creatorin, kun määrittelemme <em>setNotes</em>-actionin:
147
+
Monen actionin dispatchaaminen vaikuttaa hieman epäkäytännölliseltä. Lisätään action creator <em>setNotes</em>, jonka avulla muistiinpanojen taulukon voi suoraan korvata. Saamme <em>createSlice</em>-funktion avulla haluamamme action creatorin, kun määrittelemme <em>setNotes</em>-actionin:
> **HUOM:**miksi emme käyttäneet koodissa promisejen ja _then_-metodilla rekisteröidyn tapahtumankäsittelijän sijaan awaitia?
214
+
> **HUOM:**Miksi emme käyttäneet koodissa promisejen ja _then_-metodilla rekisteröidyn tapahtumankäsittelijän sijaan awaitia?
215
215
>
216
216
> await toimii ainoastaan <i>async</i>-funktioiden sisällä, ja <i>index.js</i>:ssä oleva koodi ei ole funktiossa, joten päädyimme tilanteen yksinkertaisuuden takia tällä kertaa jättämään <i>async</i>:in käyttämättä.
217
217
218
218
Päätetään kuitenkin siirtää muistiinpanojen alustus <i>App</i>-komponentiin, eli kuten yleensä dataa palvelimelta haettaessa, käytetään <i>effect hookia</i>:
Hookin useEffect käyttö aiheuttaa eslint-varoituksen:
250
+
Hookin useEffect käyttö aiheuttaa ESLint-varoituksen:
251
251
252
252

253
253
@@ -265,7 +265,7 @@ const App = () => {
265
265
}
266
266
```
267
267
268
-
Nyt komponentin _App_ sisällä määritelty muuttuja <i>dispatch</i> eli käytännössä Redux-storen dispatch-funktio on lisätty useEffectille parametrina annettuun taulukkoon. **Jos** dispatch-muuttujan sisältö muuttuisi ohjelman suoritusaikana, suoritettaisiin efekti uudelleen, näin ei kuitenkaan ole, eli varoitus on tässä tilanteessa oikeastaan aiheeton.
268
+
Nyt komponentin _App_ sisällä määritelty muuttuja <i>dispatch</i> eli käytännössä Redux-storen dispatch-funktio on lisätty useEffectille parametrina annettuun taulukkoon. **Jos** dispatch-muuttujan sisältö muuttuisi ohjelman suoritusaikana, suoritettaisiin efekti uudelleen. Näin ei kuitenkaan ole, eli varoitus on tässä tilanteessa oikeastaan aiheeton.
269
269
270
270
Toinen tapa päästä eroon varoituksesta olisi disabloida se kyseisen rivin kohdalta:
271
271
@@ -283,9 +283,9 @@ const App = () => {
283
283
}
284
284
```
285
285
286
-
Yleisesti ottaen eslint-virheiden disabloiminen ei ole hyvä idea, joten vaikka kyseisen eslint-säännön tarpeellisuus onkin aiheuttanut [kiistelyä](https://github.com/facebook/create-react-app/issues/6880), pitäydytään ylemmässä ratkaisussa.
286
+
Yleisesti ottaen ESLint-virheiden disabloiminen ei ole hyvä idea, joten vaikka kyseisen ESLint-säännön tarpeellisuus onkin aiheuttanut [kiistelyä](https://github.com/facebook/create-react-app/issues/6880), pitäydytään ylemmässä ratkaisussa.
287
287
288
-
Lisää hookien riippuvuuksien määrittelyn tarpeesta [Reactin dokumentaatiossa](https://reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies).
288
+
Lisää hookien riippuvuuksien määrittelyn tarpeesta on [Reactin dokumentaatiossa](https://reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies).
289
289
290
290
Voimme toimia samoin myös uuden muistiinpanon luomisen suhteen. Laajennetaan palvelimen kanssa kommunikoivaa koodia:
291
291
@@ -360,7 +360,7 @@ Sovelluksen tämänhetkinen koodi on [GitHubissa](https://github.com/fullstack-h
360
360
361
361
#### 6.13 anekdootit ja backend, step1
362
362
363
-
Hae sovelluksen käynnistyessä anekdootit json-serverillä toteutetusta backendistä.
363
+
Hae sovelluksen käynnistyessä anekdootit JSON Serverillä toteutetusta backendistä.
364
364
365
365
Backendin alustavan sisällön saat esim. [täältä](https://github.com/fullstack-hy2020/misc/blob/master/anecdotes.json).
366
366
@@ -372,23 +372,23 @@ Muuta uusien anekdoottien luomista siten, että anekdootit talletetaan backendii
372
372
373
373
<divclass="content">
374
374
375
-
### Asynkroniset actionit ja redux thunk
375
+
### Asynkroniset actionit ja Redux Thunk
376
376
377
-
Lähestymistapamme on melko hyvä, mutta siinä mielessä ikävä, että palvelimen kanssa kommunikointi tapahtuu komponentit määrittelevien funktioiden koodissa. Olisi parempi, jos kommunikointi voitaisiin abstrahoida komponenteilta siten, että niiden ei tarvitsisi kuin kutsua sopivaa <i>action creatoria</i>, esim. <i>App</i> alustaisi sovelluksen tilan seuraavasti:
377
+
Lähestymistapamme on melko hyvä, mutta siinä mielessä ikävä, että palvelimen kanssa kommunikointi tapahtuu komponentit määrittelevien funktioiden koodissa. Olisi parempi, jos kommunikointi voitaisiin abstrahoida komponenteilta siten, että niiden ei tarvitsisi kuin kutsua sopivaa <i>action creatoria</i>. Esim. <i>App</i> voisi alustaa sovelluksen tilan seuraavasti:
378
378
379
379
```js
380
380
constApp= () => {
381
381
constdispatch=useDispatch()
382
382
383
383
useEffect(() => {
384
384
dispatch(initializeNotes())
385
-
},[dispatch])
385
+
},[dispatch])
386
386
387
387
// ...
388
388
}
389
389
```
390
390
391
-
ja <i>NoteForm</i> loisi uuden muistiinpanon seuraavasti:
391
+
<i>NoteForm</i> puolestaan loisi uuden muistiinpanon seuraavasti:
392
392
393
393
```js
394
394
constNewNote= () => {
@@ -405,9 +405,9 @@ const NewNote = () => {
405
405
}
406
406
```
407
407
408
-
Molemmat komponentit dispatchaisivat ainoastaan actionin, välittämättä siitä, että taustalla tapahtuu todellisuudessa palvelimen kanssa tapahtuvaa kommunikointia. Tämän kaltaisten <i>asynkronisten actioneiden</i> käyttö onnistuu [Redux Thunk](https://github.com/reduxjs/redux-thunk)-kirjaston avulla. Kirjaston käyttö ei vaadi ylimääräistä konfiguraatiota, kun Redux-store on luotu Redux Toolkitin <em>configureStore</em>-funktiolla.
408
+
Molemmat komponentit dispatchaisivat ainoastaan actionin välittämättä siitä, että taustalla tapahtuu todellisuudessa palvelimen kanssa tapahtuvaa kommunikointia. Tämän kaltaisten <i>asynkronisten actioneiden</i> käyttö onnistuu [Redux Thunk](https://github.com/reduxjs/redux-thunk)-kirjaston avulla. Kirjaston käyttö ei vaadi ylimääräistä konfiguraatiota, kun Redux-store on luotu Redux Toolkitin <em>configureStore</em>-funktiolla.
Sisemmässä funktiossaan, eli <i>asynkronisessa actionissa</i>, operaatio hakee ensin palvelimelta kaikki muistiinpanot ja sen jälkeen <i>dispatchaa</i> muistiinpanot storeen lisäävän actionin, <em>setNotes</em>.
440
+
Sisemmässä funktiossaan eli <i>asynkronisessa actionissa</i> operaatio hakee ensin palvelimelta kaikki muistiinpanot ja sen jälkeen <i>dispatchaa</i> muistiinpanot storeen lisäävän actionin, <em>setNotes</em>.
441
441
442
442
Komponentti <i>App</i> voidaan nyt määritellä seuraavasti:
443
443
@@ -448,7 +448,7 @@ const App = () => {
448
448
// highlight-start
449
449
useEffect(() => {
450
450
dispatch(initializeNotes())
451
-
},[dispatch])
451
+
},[dispatch])
452
452
// highlight-end
453
453
454
454
return (
@@ -461,7 +461,7 @@ const App = () => {
461
461
}
462
462
```
463
463
464
-
Ratkaisu on elegantti, muistiinpanojen alustuslogiikka on eriytetty kokonaan React-komponenttien ulkopuolelle.
464
+
Ratkaisu on elegantti, sillä muistiinpanojen alustuslogiikka on eriytetty kokonaan React-komponenttien ulkopuolelle.
465
465
466
466
Korvataan seuraavaksi <em>createSlice</em>-funktion avulla toteutettu <em>createNote</em> -action creator saman nimisellä asynkronisella action creatorilla:
Periaate on jälleen sama, ensin suoritetaan asynkroninen operaatio, ja sen valmistuttua <i>dispatchataan</i> storen tilaa muuttava action. Redux Toolkit tarjoaa monia työkaluja asynkronisen tilanhallinnan helpottamiseksi. Tähän käyttötarkoitukseen soveltuvat mm. [createAsyncThunk](https://redux-toolkit.js.org/api/createAsyncThunk)-funktio ja [RTK Query](https://redux-toolkit.js.org/rtk-query/overview)-API.
522
+
Periaate on jälleen sama. Ensin suoritetaan asynkroninen operaatio, ja sen valmistuttua <i>dispatchataan</i> storen tilaa muuttava action. Redux Toolkit tarjoaa monia työkaluja asynkronisen tilanhallinnan helpottamiseksi. Tähän käyttötarkoitukseen soveltuvat mm. [createAsyncThunk](https://redux-toolkit.js.org/api/createAsyncThunk)-funktio ja [RTK Query](https://redux-toolkit.js.org/rtk-query/overview)-API.
523
523
524
524
Komponentti <i>NewNote</i> muuttuu seuraavasti:
525
525
@@ -537,13 +537,13 @@ const NewNote = () => {
537
537
return (
538
538
<form onSubmit={addNote}>
539
539
<input name="note"/>
540
-
<button type="submit">lisää</button>
540
+
<button type="submit">add</button>
541
541
</form>
542
542
)
543
543
}
544
544
```
545
545
546
-
Siistitään lopuksi vielä hieman <i>index.js</i>-tiedostoa, siirtämällä Redux-storen luontiin liittyvän koodin omaan, <i>store.js</i>-tiedostoonsa:
546
+
Siistitään lopuksi vielä hieman <i>index.js</i>-tiedostoa siirtämällä Redux-storen luontiin liittyvä koodi erilliseen <i>store.js</i>-tiedostoon:
547
547
548
548
```js
549
549
import { configureStore } from'@reduxjs/toolkit'
@@ -593,7 +593,6 @@ Muuta Redux-storen alustus tapahtumaan Redux Thunk -kirjaston avulla toteutettuu
593
593
594
594
Muuta myös uuden anekdootin luominen tapahtumaan Redux Thunk -kirjaston avulla toteutettuihin asynkronisiin actioneihin.
595
595
596
-
597
596
#### 6.17 anekdootit ja backend, step5
598
597
599
598
Äänestäminen ei vielä talleta muutoksia backendiin. Korjaa tilanne Redux Thunk -kirjastoa hyödyntäen.
@@ -615,7 +614,7 @@ Toteuta action creator, joka mahdollistaa notifikaation antamisen seuraavasti:
0 commit comments