diff --git a/GLOSSARY.md b/GLOSSARY.md
index 8d7c725c..eab2783a 100644
--- a/GLOSSARY.md
+++ b/GLOSSARY.md
@@ -43,3 +43,5 @@
- **codebase**: koodipohja
- **property**: en keksinyt järkevää suomennosta, property
- **scope**: käyttöalue
+- **bubbles**: kuplii (bublling in JavaScript)
+- **capture**: nappaus (capture in JavaScript)
diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md
index 7c5adb11..5aa70259 100644
--- a/src/content/learn/tutorial-tic-tac-toe.md
+++ b/src/content/learn/tutorial-tic-tac-toe.md
@@ -1,31 +1,31 @@
---
-title: 'Tutorial: Tic-Tac-Toe'
+title: 'Opas: Ristinolla'
---
-You will build a small tic-tac-toe game during this tutorial. This tutorial does not assume any existing React knowledge. The techniques you'll learn in the tutorial are fundamental to building any React app, and fully understanding it will give you a deep understanding of React.
+Tulet rakentamaan pienen ristinolla-pelin tässä oppaassa. Tämä opas ei oleta aikaisempaa React-osaamista. Tekniikat, joita opit oppaan aikana ovat perustavanlaatuisia mille tahansa React-sovellukselle ja niiden ymmärtäminen antaa sinulle syvällisen ymmärryksen Reactista.
-This tutorial is designed for people who prefer to **learn by doing** and want to quickly try making something tangible. If you prefer learning each concept step by step, start with [Describing the UI.](/learn/describing-the-ui)
+Tämä opas on tarkoitettu henkilöille, jotka suosivat **oppimaan tekemällä** ja haluavat nopeasti kokeilla tehdä jotain konkreettista. Jos suosit oppimista jokaisen käsitteen vaiheittain, aloita [Käyttöliittymän kuvaaminen](/learn/describing-the-ui) sivulta.
-The tutorial is divided into several sections:
+Tämä opas on jaettu useaan osaan:
-- [Setup for the tutorial](#setup-for-the-tutorial) will give you **a starting point** to follow the tutorial.
-- [Overview](#overview) will teach you **the fundamentals** of React: components, props, and state.
-- [Completing the game](#completing-the-game) will teach you **the most common techniques** in React development.
-- [Adding time travel](#adding-time-travel) will give you **a deeper insight** into the unique strengths of React.
+- [Oppaan asennusvaihe](#setup-for-the-tutorial) antaa sinulle *lähtökohdan** oppaan seuraamiseen.
+- [Yleiskatsaus](#overview) opettaa sinulle Reactin **perusteet**: komponentit, propsit, ja tilan.
+- [Pelin viimeistely](#completing-the-game) opettaa sinulle **yleisimmät tekniikat** React kehityksessä.
+- [Aikamatkustuksen lisääminen](#adding-time-travel) opettaa sinulle **syvällisen ymmärryksen** Reactin uniikkeihin vahvuuksiin.
-### What are you building? {/*what-are-you-building*/}
+### Mitä olet rakentamassa? {/*what-are-you-building*/}
-In this tutorial, you'll build an interactive tic-tac-toe game with React.
+Tässä oppaassa tulet rakentamaan interaktiivisen ristinolla-pelin Reactilla.
-You can see what it will look like when you're finished here:
+Näet alla miltä se tulee lopulta näyttämään kun saat sen valmiiksi:
@@ -57,9 +57,9 @@ function Board({ xIsNext, squares, onPlay }) {
const winner = calculateWinner(squares);
let status;
if (winner) {
- status = 'Winner: ' + winner;
+ status = 'Voittaja: ' + winner;
} else {
- status = 'Next player: ' + (xIsNext ? 'X' : 'O');
+ status = 'Seuraava pelaajaa: ' + (xIsNext ? 'X' : 'O');
}
return (
@@ -103,9 +103,9 @@ export default function Game() {
const moves = history.map((squares, move) => {
let description;
if (move > 0) {
- description = 'Go to move #' + move;
+ description = 'Siirry liikkeeseen #' + move;
} else {
- description = 'Go to game start';
+ description = 'Siirry pelin alkuun';
}
return (
@@ -194,15 +194,15 @@ body {
-If the code doesn't make sense to you yet, or if you are unfamiliar with the code's syntax, don't worry! The goal of this tutorial is to help you understand React and its syntax.
+Jos et saa selvää koodista vielä taikka koodin syntaksi ei ole tuttua, älä huoli! Tämän oppaan tavoite on auttaa sinua ymmärtämään Reactia ja sen syntaksia.
-We recommend that you check out the tic-tac-toe game above before continuing with the tutorial. One of the features that you'll notice is that there is a numbered list to the right of the game's board. This list gives you a history of all of the moves that have occurred in the game, and it is updated as the game progresses.
+Suosittelemme, että kokeilet peliä ennen kuin jatkat oppaan kanssa. Yksi pelin ominaisuuksista on, että pelilaudan oikealla puolella on numeroitu lista. Tämä lista näyttää pelin kaikki siirrot ja päivittyy pelin edetessä.
-Once you've played around with the finished tic-tac-toe game, keep scrolling. You'll start with a simpler template in this tutorial. Our next step is to set you up so that you can start building the game.
+Kun olet pelannut peliä, jatka oppaan kanssa. Tulet aloittamaan yksinkertaisemmasta pohjasta. Seuraava askel on asentaa ympäristö, jotta voit aloittaa pelin rakentamisen.
-## Setup for the tutorial {/*setup-for-the-tutorial*/}
+## Oppaan asennusvaihe {/*setup-for-the-tutorial*/}
-In the live code editor below, click **Fork** in the top-right corner to open the editor in a new tab using the website CodeSandbox. CodeSandbox lets you write code in your browser and preview how your users will see the app you've created. The new tab should display an empty square and the starter code for this tutorial.
+Alla olevassa koodieditorissa, paina **Forkkaa* oikeassa yläreunassa avataksesi editorin uuteen välilehteen käyttäen CodeSandboxia. CodeSandbox antaa sinun kirjoittaa koodia selaimessasi ja esikatsella miten käyttäjäsi näkevät luomasi sovelluksen. Uuden välilehden tulisi näyttää tyhjä ruutu ja tämän oppaan aloituskoodi.
@@ -263,31 +263,33 @@ body {
You can also follow this tutorial using your local development environment. To do this, you need to:
-1. Install [Node.js](https://nodejs.org/en/)
-1. In the CodeSandbox tab you opened earlier, press the top-left corner button to open the menu, and then choose **File > Export to ZIP** in that menu to download an archive of the files locally
-1. Unzip the archive, then open a terminal and `cd` to the directory you unzipped
-1. Install the dependencies with `npm install`
-1. Run `npm start` to start a local server and follow the prompts to view the code running in a browser
+Voit myös seurata tätä opasta paikallisessa kehitysympäristössä. Tämä vaatii:
-If you get stuck, don't let this stop you! Follow along online instead and try a local setup again later.
+1. Asenna [Node.js](https://nodejs.org/en/)
+1. Aikaisemmin avatussa CodeSandbox -välilehdessä, paina vasemmassa yläreunassa olevaa painiketta ja valitse **File > Export to ZIP** ladataksesi arkiston tiedostoista.
+1. Pura arkisto, ja avaa sitten terminaali ja siirry `cd`:llä purettuun hakemistoon
+1. Asenna riippuvuudet `npm install` komennolla
+1. Suorita `npm start` käynnistääksesi paikallisen palvelimen ja seuraa kehotuksia nähdäksesi koodin selaimessa
+
+Jos jäät jumiin, älä anna tämän estää! Seuraa opasta verkossa ja kokeile paikallista asennusta myöhemmin uudelleen.
-## Overview {/*overview*/}
+## Yleiskatsaus {/*overview*/}
-Now that you're set up, let's get an overview of React!
+Nyt kun olet valmis, annetaan yleiskatsaus Reactista!
-### Inspecting the starter code {/*inspecting-the-starter-code*/}
+### Aloituskoodin tarkastelu {/*inspecting-the-starter-code*/}
-In CodeSandbox you'll see three main sections:
+CodeSandboxissa näet kolme eri osiota:
-![CodeSandbox with starter code](../images/tutorial/react-starter-code-codesandbox.png)
+![CodeSandbox aloituskoodilla](../images/tutorial/react-starter-code-codesandbox.png)
-1. The _Files_ section with a list of files like `App.js`, `index.js`, `styles.css` and a folder called `public`
-1. The _code editor_ where you'll see the source code of your selected file
-1. The _browser_ section where you'll see how the code you've written will be displayed
+1. _Files_ osio, jossa on listaus tiedostoista kuten `App.js`, `index.js`, `styles.css` ja hakemisto nimeltään `public`
+1. _Koodieditori_, jossa näet valitun tiedoston lähdekoodin
+1. _Selain_, jossa näet miltä kirjoittamasi koodi näyttää
-The `App.js` file should be selected in the _Files_ section. The contents of that file in the _code editor_ should be:
+`App.js` tiedoston tulisi olla valittuna _Files_ osiossa. Tiedoston sisältö _koodieditorissa_ tulisi olla seuraava:
```jsx
export default function Square() {
@@ -295,15 +297,15 @@ export default function Square() {
}
```
-The _browser_ section should be displaying a square with a X in it like this:
+_Selaimen_ tulisi näyttää neliö, jossa on X:
-![x-filled square](../images/tutorial/x-filled-square.png)
+![Neliö, jossa on X](../images/tutorial/x-filled-square.png)
-Now let's have a look at the files in the starter code.
+Katsotaan nyt aloituskoodin tiedostoja.
#### `App.js` {/*appjs*/}
-The code in `App.js` creates a _component_. In React, a component is a piece of reusable code that represents a part of a user interface. Components are used to render, manage, and update the UI elements in your application. Let's look at the component line by line to see what's going on:
+Koodi `App.js` tiedostossa luo _komponentin_. Reactissa komponentti on pala uudelleenkäytettävää koodia, joka edustaa palan käyttöliittymää. Komponentteja käytetään renderöimään, hallitsemaan ja päivittämään sovelluksesi UI elementtejä. Katsotaan komponenttia rivi riviltä nähdäksemme mitä tapahtuu:
```js {1}
export default function Square() {
@@ -311,7 +313,7 @@ export default function Square() {
}
```
-The first line defines a function called `Square`. The `export` JavaScript keyword makes this function accessible outside of this file. The `default` keyword tells other files using your code that it's the main function in your file.
+Ensimmäinen rivi määrittelee funktion nimeltään `Square`. `export` -JavaScript avainsana tekee funktion saavutettavaksi tämän tiedoston ulkopuolelle. `default` avainsana kertoo muille tiedostoille, että tämä on pääfunktio tiedostossasi.
```js {2}
export default function Square() {
@@ -319,15 +321,15 @@ export default function Square() {
}
```
-The second line returns a button. The `return` JavaScript keyword means whatever comes after is returned as a value to the caller of the function. `` closes the JSX element to indicate that any following content shouldn't be placed inside the button.
+Seuraava koodirivi palauttaa painonapin. `return` -JavaScript avainsanan tarkoittaa, mitä ikinä sen jälkeen tulee, palautetaan se arvo funktion kutsujalle. `` sulkee JSX elementin osoittaen, että mitään seuraavaa sisältöä ei tulisi sijoittaa painikkeen sisälle.
#### `styles.css` {/*stylescss*/}
-Click on the file labeled `styles.css` in the _Files_ section of CodeSandbox. This file defines the styles for your React app. The first two _CSS selectors_ (`*` and `body`) define the style of large parts of your app while the `.square` selector defines the style of any component where the `className` property is set to `square`. In your code, that would match the button from your Square component in the `App.js` file.
+Paina tiedostosta nimeltään `styles.css` CodeSandboxin _Files_ osiossa. Tämä tiedosto määrittelee React sovelluksesi tyylin. Ensimmäiset kaksi _CSS selektoria_ (`*` ja `body`) määrittävät suuren osan sovelluksestasi tyyleistä, kun taas `.square` selektori määrittää minkä tahansa komponentin tyylin, jossa `className` ominaisuus on asetettu `square` arvoon. Koodissasi tämä vastaa painiketta `Square` komponentissa `App.js` tiedostossa.
#### `index.js` {/*indexjs*/}
-Click on the file labeled `index.js` in the _Files_ section of CodeSandbox. You won't be editing this file during the tutorial but it is the bridge between the component you created in the `App.js` file and the web browser.
+Paina tiedostosta nimeltään `index.js` CodeSandboxin _Files_ osiossa. Et tule muokkaamaan tätä tiedostoa oppaan aikana, mutta se on silta `App.js` tiedostossa luomasi komponentin ja selaimen välillä.
```jsx
import { StrictMode } from 'react';
@@ -337,20 +339,20 @@ import './styles.css';
import App from './App';
```
-Lines 1-5 brings all the necessary pieces together:
+Rivit 1-5 tuovat kaikki tarvittavat palaset yhteen:
* React
-* React's library to talk to web browsers (React DOM)
-* the styles for your components
-* the component you created in `App.js`.
+* Reactin kirjasto, jolla se juttelee selaimen kanssa (React DOM)
+* komponenttiesi tyylit
+* luomasi komponentti `App.js` tiedostossa.
-The remainder of the file brings all the pieces together and injects the final product into `index.html` in the `public` folder.
+Loput tiedostosta tuo kaikki palaset yhteen ja palauttaa lopputuotteen `index.html` tiedostoon `public` hakemistossa.
-### Building the board {/*building-the-board*/}
+### Pelilaudan rakentaminen {/*building-the-board*/}
-Let's get back to `App.js`. This is where you'll spend the rest of the tutorial.
+Palataan takaisin `App.js` tiedostoon. Tämä on missä tulet viettämään lopun oppaan ajasta.
-Currently the board is only a single square, but you need nine! If you just try and copy paste your square to make two squares like this:
+Nykyisillään pelilauta on vain yksi neliö, mutta tarvitset yhdeksän! Voit yrittää vain kopioida ja liittää neliösi tehdäksesi kaksi neliötä näin:
```js {2}
export default function Square() {
@@ -358,7 +360,7 @@ export default function Square() {
}
```
-You'll get this error:
+Saat tämän virheen:
@@ -366,7 +368,7 @@ You'll get this error:
-React components need to return a single JSX element and not multiple adjacent JSX elements like two buttons. To fix this you can use *fragments* (`<>` and `>`) to wrap multiple adjacent JSX elements like this:
+React komponenttien täytyy palauttaa yksi JSX elementti, ei useampia vierekkäisiä JSX elementtejä kun kaksi painonappia. Korjataksesi tämän käytä *fragmenttejä* (`<>` ja `>`) käärimään useampia vierekkäisiä JSX elementtejä näin:
```js {3-6}
export default function Square() {
@@ -379,17 +381,17 @@ export default function Square() {
}
```
-Now you should see:
+Nyt näet:
-![two x-filled squares](../images/tutorial/two-x-filled-squares.png)
+![kaksi x:llä täytettyä neliötä](../images/tutorial/two-x-filled-squares.png)
-Great! Now you just need to copy-paste a few times to add nine squares and...
+Hyvä! Nyt sinun tulee kopioida ja littää muutaman kerran saadaksesi yhdeksän neliötä ja sitten....
-![nine x-filled squares in a line](../images/tutorial/nine-x-filled-squares.png)
+![yhdeksän x:llä täyettyä neliötä rivissä](../images/tutorial/nine-x-filled-squares.png)
-Oh no! The squares are all in a single line, not in a grid like you need for our board. To fix this you'll need to group your squares into rows with `div`s and add some CSS classes. While you're at it, you'll give each square a number to make sure you know where each square is displayed.
+Voi ei! Neliöt ovat kaikki yhdessä rivissä eikä ruudukossa kuten tarvitset sen pelilaudalla. Korjataksesi tämän sinun tulee ryhmitellä neliöt riveihin `div` elementeillä ja lisätä muutama CSS luokka. Samalla kun teet tämän, annat jokaiselle neliölle numeron varmistaaksesi, että tiedät missä jokainen neliö näytetään.
-In the `App.js` file, update the `Square` component to look like this:
+`App.js` tiedostossa, päivitä `Square` komponentti näyttämään tältä:
```js {3-19}
export default function Square() {
@@ -415,11 +417,11 @@ export default function Square() {
}
```
-The CSS defined in `styles.css` styles the divs with the `className` of `board-row`. Now that you've grouped your components into rows with the styled `div`s you have your tic-tac-toe board:
+`styles.css` tiedostossa määritelty CSS tyylittää divit `className`:n `board-row` arvolla. Nyt kun olet ryhmitellyt komponenttisi riveihin tyylitetyillä `div` elementeillä, sinulla on ristinolla-pelilauta:
-![tic-tac-toe board filled with numbers 1 through 9](../images/tutorial/number-filled-board.png)
+![ristinolla-pelilauta numeroitu yhdestä yhdeksään](../images/tutorial/number-filled-board.png)
-But you now have a problem. Your component named `Square`, really isn't a square anymore. Let's fix that by changing the name to `Board`:
+Mutta nyt sinulla on ongelma. Komponenttisi `Square` ei enää ole neliö. Korjataksesi tämän, muuta nimi `Square` komponentille `Board`:iksi:
```js {1}
export default function Board() {
@@ -427,7 +429,7 @@ export default function Board() {
}
```
-At this point your code should look something like this:
+Tässä kohtaa, koodisi tuli näyttää tämänkaltaiselta:
@@ -504,15 +506,15 @@ body {
-Psssst... That's a lot to type! It's okay to copy and paste code from this page. However, if you're up for a little challenge, we recommend only copying code that you've manually typed at least once yourself.
+Pst... Tuossa on aika paljon kirjoitettavaa! On ihan ok kopioida ja liittää koodia tältä sivulta. Jos kuitenkin haluat haastetta, suosittelemme kopioida vain koodia, jonka olet kirjoittanut ainakin kerran itse.
-### Passing data through props {/*passing-data-through-props*/}
+### Datan välittäminen propseilla {/*passing-data-through-props*/}
-Next, you'll want to change the value of a square from empty to "X" when the user clicks on the square. With how you've built the board so far you would need to copy-paste the code that updates the square nine times (once for each square you have)! Instead of copy-pasting, React's component architecture allows you to create a reusable component to avoid messy, duplicated code.
+Seuraavaksi haluat muuttaa neliön arvon tyhjästä X:ksi kun käyttäjä painaa neliötä. Tällä hetkellä sinun täytyisi kopioida ja liittää koodi, joka päivittää neliön yhdeksän kertaa (kerran jokaiselle neliölle)! Sen sijaan, että kopioisit ja liittäisit, Reactin komponenttiarkkitehtuuri antaa sinun luoda uudelleenkäytettävän komponentin välttääksesi sotkuisen, toistuvan koodin.
-First, you are going to copy the line defining your first square (``) from your `Board` component into a new `Square` component:
+Ensiksi, kopioit rivin, joka määrittelee ensimmäisen neliösi (``) `Board` komponentistasi uuteen `Square` komponenttiin:
```js {1-3}
function Square() {
@@ -524,7 +526,7 @@ export default function Board() {
}
```
-Then you'll update the Board component to render that `Square` component using JSX syntax:
+Sitten päivität `Board` komponentin renderöimään sen `Square` komponentin käyttäen JSX syntaksia:
```js {5-19}
// ...
@@ -551,15 +553,15 @@ export default function Board() {
}
```
-Note how unlike the browser `div`s, your own components `Board` and `Square` must start with a capital letter.
+Huomaa miten toisin kuin selainten `div`:it, omat komponenttisi `Board` ja `Square` täytyy alkaa isolla kirjaimella.
-Let's take a look:
+Katsotaanpa:
-![one-filled board](../images/tutorial/board-filled-with-ones.png)
+![pelilauta täytetty ykkösillä](../images/tutorial/board-filled-with-ones.png)
-Oh no! You lost the numbered squares you had before. Now each square says "1". To fix this, you will use *props* to pass the value each square should have from the parent component (`Board`) to its child (`Square`).
+Voi ei! Menetit numeroidut neliöt, jotka sinulla oli aiemmin. Nyt jokaisessa neliössä lukee "1". Korjataksesi tämän, käytä *propseja* välittääksesi arvon, jonka jokaisen neliön tulisi saada vanhemmalta komponentilta (`Board`) sen alakomponentille (`Square`).
-Update the `Square` component to read the `value` prop that you'll pass from the `Board`:
+Päivitä `Square` komponentti lukemaan `value` propsi, jonka välität `Board` komponentilta:
```js {1}
function Square({ value }) {
@@ -567,9 +569,9 @@ function Square({ value }) {
}
```
-`function Square({ value })` indicates the Square component can be passed a prop called `value`.
+`function Square({ value })` kertoo, että `Square` komponentille voidaan välittää `value` niminen propsi.
-Now you want to display that `value` instead of `1` inside every square. Try doing it like this:
+Nyt haluat näyttää `value` arvon `1`:n sijaan jokaisessa neliössä. Kokeile tehdä se näin:
```js {2}
function Square({ value }) {
@@ -577,11 +579,11 @@ function Square({ value }) {
}
```
-Oops, this is not what you wanted:
+Oho, tämä ei ollut mitä halusit:
-![value-filled board](../images/tutorial/board-filled-with-value.png)
+![pelilauta täytetty value tekstillä](../images/tutorial/board-filled-with-value.png)
-You wanted to render the JavaScript variable called `value` from your component, not the word "value". To "escape into JavaScript" from JSX, you need curly braces. Add curly braces around `value` in JSX like so:
+Halusit renderöidä JavaScript muuttujan nimeltään `value` komponentistasi, et sanan "value". Päästäksesi "takaisin JavaScriptiin" JSX:stä, tarvitset aaltosulkeet. Lisää aaltosulkeet `value`:n ympärille JSX:ssä näin:
```js {2}
function Square({ value }) {
@@ -589,11 +591,11 @@ function Square({ value }) {
}
```
-For now, you should see an empty board:
+Toistaiseksi, sinun tulisi nähdä tyhjä pelilauta:
-![empty board](../images/tutorial/empty-board.png)
+![tyhjä pelilauta](../images/tutorial/empty-board.png)
-This is because the `Board` component hasn't passed the `value` prop to each `Square` component it renders yet. To fix it you'll add the `value` prop to each `Square` component rendered by the `Board` component:
+Näin tapahtuu, koska `Board` komponentti ei ole välittänyt `value` propseja jokaiselle `Square` komponentille, jonka se renderöi. Korjataksesi tämän, lisää `value` propsi jokaiselle `Square` komponentille, jonka `Board` komponentti renderöi:
```js {5-7,10-12,15-17}
export default function Board() {
@@ -619,11 +621,11 @@ export default function Board() {
}
```
-Now you should see a grid of numbers again:
+Nyt sinun tulisi nähdä numeroitu ruudukko taas:
-![tic-tac-toe board filled with numbers 1 through 9](../images/tutorial/number-filled-board.png)
+![ristinolla-pelilauta täytetty yhdestä yhdeksään](../images/tutorial/number-filled-board.png)
-Your updated code should look like this:
+Päivitetyn koodisi tulisi näyttää tämänkaltaiselta:
@@ -702,9 +704,9 @@ body {
-### Making an interactive component {/*making-an-interactive-component*/}
+### Interaktiivisen komponentin luominen {/*making-an-interactive-component*/}
-Let's fill the `Square` component with an `X` when you click it. Declare a function called `handleClick` inside of the `Square`. Then, add `onClick` to the props of the button JSX element returned from the `Square`:
+Täytetään `Square` komponentti `X`:llä kun klikkaat sitä. Määritä funktio nimeltään `handleClick` `Square` komponentin sisällä. Sitten, lisää `onClick` prosi painonapin JSX elementtiin, joka palautetaan `Square` komponentista:
```js {2-4,9}
function Square({ value }) {
@@ -723,19 +725,19 @@ function Square({ value }) {
}
```
-If you click on a square now, you should see a log saying `"clicked!"` in the _Console_ tab at the bottom of the _Browser_ section in CodeSandbox. Clicking the square more than once will log `"clicked!"` again. Repeated console logs with the same message will not create more lines in the console. Instead, you will see an incrementing counter next to your first `"clicked!"` log.
+Jos painat neliöstä nyt, sinun tulisi nähdä loki, jossa lukee `"clicked!"` _Console_ välilehdellä _Browser_ osiossa CodeSandboxissa. Painamalla neliötä useammin kuin kerran, lokiin tulee uusi rivi, jossa lukee `"clicked!"`. Toistuvat lokit samalla viestillä eivät luo uusia rivejä lokiin. Sen sijaan, näet kasvavan laskurin ensimmäisen `"clicked!"` lokin vieressä.
-If you are following this tutorial using your local development environment, you need to open your browser's Console. For example, if you use the Chrome browser, you can view the Console with the keyboard shortcut **Shift + Ctrl + J** (on Windows/Linux) or **Option + ⌘ + J** (on macOS).
+Jos seuraat tätä opasta paikallisessa kehitysympäristössä, sinun tulee avata selaimen konsoli. Esimerkiksi, jos käytät Chrome selainta, voit avata konsolin näppäinyhdistelmällä **Shift + Ctrl + J** (Windows/Linux) tai **Option + ⌘ + J** (macOS).
-As a next step, you want the Square component to "remember" that it got clicked, and fill it with an "X" mark. To "remember" things, components use *state*.
+Seuraavaksi, haluat Square komponentin "muistavat", että sitä painettiin, ja täyttää sen "X" merkillä. Komponentit käyttävät *tilaa* muistaakseen asioita.
-React provides a special function called `useState` that you can call from your component to let it "remember" things. Let's store the current value of the `Square` in state, and change it when the `Square` is clicked.
+React tarjoaa erityisen funktion nimeltään `useState`, jota voit kutsua komponentistasi, jotta se "muistaa" asioita. Tallennetaan `Square` komponentin nykyinen arvo tilaan ja muutetaan sitä, kun `Square` painetaan.
-Import `useState` at the top of the file. Remove the `value` prop from the `Square` component. Instead, add a new line at the start of the `Square` that calls `useState`. Have it return a state variable called `value`:
+Importtaa `useState` tiedoston ylläosassa. Poista `value` propsi `Square` komponentista. Sen sijaan, lisää uusi rivi `Square` komponentin alkuun, joka kutsuu `useState`:a. Anna sen palauttaa tilamuuttuja nimeltään `value`:
```js {1,3,4}
import { useState } from 'react';
@@ -747,9 +749,9 @@ function Square() {
//...
```
-`value` stores the value and `setValue` is a function that can be used to change the value. The `null` passed to `useState` is used as the initial value for this state variable, so `value` here starts off equal to `null`.
+`value` pitää sisällään arvon ja `setValue` on funktio, jota voidaan käyttää muuttamaan arvoa. `null`, joka välitetään `useState`:lle, käytetään alkuperäisenä arvona tälle tilamuuttujalle, joten `value` on aluksi `null`.
-Since the `Square` component no longer accepts props anymore, you'll remove the `value` prop from all nine of the Square components created by the Board component:
+Koska `Square` komponentti ei enää hyväksy propseja, poistat `value` propin kaikista yhdeksästä `Square` komponentista, jotka `Board` komponentti luo:
```js {6-8,11-13,16-18}
// ...
@@ -776,7 +778,7 @@ export default function Board() {
}
```
-Now you'll change `Square` to display an "X" when clicked. Replace the `console.log("clicked!");` event handler with `setValue('X');`. Now your `Square` component looks like this:
+Nyt muutat `Square`:n näyttämään "X":n kun sitä painetaan. Korvaa `console.log("clicked!");` tapahtumankäsittelijä `setValue('X');`:lla. Nyt `Square` komponenttisi näyttää tältä:
```js {5}
function Square() {
@@ -797,13 +799,13 @@ function Square() {
}
```
-By calling this `set` function from an `onClick` handler, you're telling React to re-render that `Square` whenever its `