Johdanto
Tässä osassa tutustutaan Next.js 13 kehykseen, joka on viimeisin versio suositusta React-pohjaisesta web-sovelluskehityskehyksestä. Next.js 13 tarjoaa joukon innovatiivisia ominaisuuksia ja työkaluja, jotka tekevät web-sovellusten rakentamisesta helpompaa ja tehokkaampaa kuin koskaan ennen.
Nykyään web-sovellukset ovat monimutkaisempia ja vaativat nopeaa käyttöönottoa, responsiivisuutta eri laitteilla sekä saumattoman käyttökokemuksen. Next.js 13 on suunniteltu vastaamaan näihin haasteisiin tarjoamalla vahvan perustan niin front-end kuin back-end -kehitykselle.
Se tuo mukanaan kehittyneitä reititysmahdollisuuksia, serverless-toiminnallisuuksia ja optimoituja suorituskykyä parantavia ominaisuuksia, jotka auttavat luomaan ammattimaisia web-sovelluksia.
Perehdytään sivujen reititykseen, komponenttien luomiseen, datan hakemiseen ja näyttämiseen, käyttäjätilien hallintaan, tietokantojen käyttöön ja moniin muihin taitoihin, jotka ovat olennaisia modernin fullstack-sovelluksen kehityksessä.
Kun pääset harjoitusten edetessä pidemmälle, huomaat varmasti oman kehittymisesi ja ymmärryksesi kasvun. Voit alkaa nähdä yhteyksiä eri käsitteiden ja tekniikoiden välillä sekä ymmärtää, miten ne yhdessä muodostavat kokonaisen web-sovelluksen. Muista, että jokainen oppimasi taito on askel eteenpäin, oli se sitten pieni tai suuri. Kehittäjänä olet osa laajaa yhteisöä, joka jakaa tietoa, ratkaisuja ja ideoita.
Verkostoituminen muiden kehittäjien kanssa, osallistuminen keskusteluihin ja tutustuminen uusiin teknologioihin voi avata uusia mahdollisuuksia ja näkökulmia.
Frontend web-sovelluksessa
Kun aloitamme Next.js 13 front-end-kehityksellä, on tärkeää ymmärtää, miten eri teknologiat toimivat yhdessä luodakseen modernin web-sovelluksen perustan.
HTML (HyperText Markup Language) on kieli, jota käytetään luomaan verkkosivujen rakenteet. Se määrittelee, miten sivu koostuu elementeistä, kuten otsikoista, kappaleista, linkeistä ja kuvista. Next.js:ssä voit kirjoittaa HTML:ää React-komponenttien muodossa, jolloin voit dynaamisesti luoda ja päivittää sivun rakenteita.
CSS (Cascading Style Sheets) on kieli, jolla määritellään verkkosivujen ulkoasu ja visuaalinen tyyli.
Voit käyttää CSS:ää muokkaamaan fontteja, värejä, taustoja ja sijoittelua. Next.js:ssä voit liittää CSS-tyylit suoraan komponentteihin tai käyttää globaaleja tyylejä määrittämään sivun yleistä ulkoasua.
JavaScript (JS) on ohjelmointikieli, joka tekee sivuista vuorovaikutteisia ja dynaamisia. Voit käyttää JavaScriptiä toteuttamaan tapahtumia, animaatioita ja käyttäjävuorovaikutusta. Next.js 13 sisältää JavaScript-ympäristön ja tarjoaa React-kirjaston avulla mahdollisuuden luoda uudelleenkäytettäviä komponentteja ja hallita sivun tilaa.
React-komponentit ja Reititys
Next.js 13 hyödyntää Reactia, suosittua JavaScript-kirjastoa, joka auttaa rakentamaan käyttäjäystävällisiä käyttöliittymiä. Käyttämällä React-komponentteja voit jakaa käyttöliittymän osiin ja käsitellä niitä erillisinä yksikköinä. Voit esimerkiksi luoda erillisen komponentin navigointipalkille, sivusisällölle ja jalkatiedolle.
Reititys tarkoittaa sitä, miten sovelluksen eri sivut ja näkymät hallitaan. Next.js 13 tarjoaa dynaamisen reititysjärjestelmän, joka helpottaa sivujen luomista ja navigointia. Voit luoda selkeitä ja kauniita reittejä, jotka vastaavat eri sivujen polkuja ja mahdollistavat käyttäjän saumattoman liikkumisen sovelluksessasi.
Reaaliaikainen Päivitys ja Hot-reloading
Next.js 13 sisältää työkaluja, jotka nopeuttavat kehitystyötäsi. Reaaliaikainen päivitys ja hot-reloading tarkoittavat, että voit nähdä muutokset heti, kun teet niitä koodiisi. Tämä mahdollistaa nopean kokeilun ja virheiden korjaamisen, mikä on erityisen hyödyllistä luodessasi käyttöliittymää.
Käytännön harjoittelu
Seuraavaksi siirrymme käytännön harjoituksiin, joissa luomme ensimmäiset React-komponentit, tutustumme sivujen reititykseen ja kokeilemme reaaliaikaista päivitystä. Näillä taidoilla voit alkaa rakentaa houkuttelevia ja toimivia käyttöliittymiä Next.js 13 -sovelluksissasi.
Käytännön Harjoitukset: Luodaan Ensimmäiset React-komponentit ja Käytetään Reititystä
Harjoitus 1: Luodaan Yksinkertainen Komponentti
- Avaa projektisi koodieditori ja navigoi “src” -hakemistoon.
- Luo uusi kansio nimeltä “components”.
- Siirry “components” -kansioon ja luo uusi tiedosto nimeltä “Header.js”.
- Avaa “Header.js” -tiedosto ja kirjoita seuraava koodi:
import React from 'react';
function Header() {
return (
<header>
<h1>Tervetuloa Next.js 13 -seikkailuun!</h1>
</header>
);
}
export default Header;
- Palaa juurikansioon ja avaa “pages” -kansio.
- Luo uusi tiedosto nimeltä “index.js”.
- Avaa “index.js” ja kirjoita seuraava koodi:
import React from 'react';
import Header from '../components/Header';
function Home() {
return (
<div>
<Header />
<p>Tervetuloa Next.js 13 -seikkailuun! Tämä on ensimmäinen sivumme.</p>
</div>
);
}
export default Home;
- Tallenna tiedostot.
Harjoitus 2: Käytetään Reititystä
- Avaa “pages” -kansiossa oleva “index.js” -tiedosto.
- Lisää tiedoston alkuun seuraava koodi:
import Link from 'next/link';
Korvaa <p>-elementti seuraavalla koodilla:
<p>Tervetuloa Next.js 13 -seikkailuun! Tämä on ensimmäinen sivumme.</p>
<p>Siirry seuraavaksi <Link href="/about">tietoa</Link>-sivulle.</p>
- Luo uusi tiedosto nimeltä “about.js” “pages” -kansioon.
- Avaa “about.js” ja kirjoita seuraava koodi:
import React from 'react';
import Header from '../components/Header';
function About() {
return (
<div>
<Header />
<p>Tervetuloa tietoa-sivulle! Täältä löydät lisää tietoa Next.js 13:sta.</p>
</div>
);
}
export default About;
- Tallenna tiedostot.
Nyt olet luonut yksinkertaisen React-komponentin “Header” sekä käyttänyt Next.js 13:n tarjoamaa reititystä siirtymiseen sivujen välillä. Voit nähdä luomasi sivut käyttämällä Next.js:n reaaliaikaista päivitystä avaamalla sovelluksen selaimessa ja navigoimalla sivuille. Seuraavaksi voit jatkaa näiden perustaitojen syventämistä ja luoda monimutkaisempia komponentteja ja reittejä. Onnea matkaan!
Harjoitus 3: Interaktiivisuus ja Tapahtumankäsittely
Interaktiivisuus on tärkeä osa web-sovelluksia, ja se saavutetaan tapahtumankäsittelyn avulla. Tässä harjoituksessa lisäämme yksinkertaisen tapahtumankäsittelyn ja interaktiivisen toiminnallisuuden sovellukseemme.
- Avaa “components” -kansiossa oleva “Header.js” -tiedosto.
- Lisää <h1>-elementin alle seuraava koodi:
<button onClick={() => alert('Hei, tämä on interaktiivinen nappi!')}>
Klikkaa minua
</button>
- Tallenna tiedosto.
Kun lisäät tämän koodin, näet nyt sivullasi painikkeen, jota klikkaamalla avautuu ilmoitus “Hei, tämä on interaktiivinen nappi!”. Tämä on yksinkertainen esimerkki tapahtumankäsittelystä. Voit käyttää onClick-ominaisuutta muihin tapahtumiin ja funktioihin, joita haluat suorittaa käyttäjän vuorovaikutuksen perusteella.
Tapahtumankäsittely ja interaktiivisuus ovat olennaisia web-sovelluksen käyttäjäkokemuksen kannalta, ja React ja Next.js tarjoavat tehokkaat välineet niiden toteuttamiseen. Jatka harjoittelemista ja kokeilemista erilaisten tapahtumien ja interaktiivisten toimintojen kanssa luodaksesi monipuolisia ja mielenkiintoisia web-sovelluksia!
Harjoitus 4: Lomakkeen Luominen ja Tiedon Näyttäminen
Lomakkeet ovat olennainen osa monia web-sovelluksia, ja niitä käytetään käyttäjien syöttämän tiedon keräämiseen. Tässä harjoituksessa luomme yksinkertaisen lomakkeen ja näytämme käyttäjän syöttämän tiedon sivulla.
- Luo uusi kansio “pages” -kansion sisälle nimeltä “contact”.
- Avaa “contact” -kansio ja luo uusi tiedosto nimeltä “index.js”.
- Avaa “index.js” ja kirjoita seuraava koodi:
import React, { useState } from 'react';
import Header from '../../components/Header';
function Contact() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
alert(`Lähetetty: Nimi - ${name}, Sähköposti - ${email}`);
};
return (
<div>
<Header />
<h2>Ota Yhteyttä</h2>
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="name">Nimi:</label>
<input
type="text"
id="name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</div>
<div>
<label htmlFor="email">Sähköposti:</label>
<input
type="email"
id="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<button type="submit">Lähetä</button>
</form>
</div>
);
}
export default Contact;
- Tallenna tiedosto.
Tämä esimerkki luo yksinkertaisen yhteydenottolomakkeen. Käyttäjä voi syöttää nimensä ja sähköpostiosoitteensa, ja kun lomake lähetetään, näytetään ilmoitus, joka sisältää syötetyn nimen ja sähköpostiosoitteen.
Tämä harjoitus osoittaa, miten voit käyttää tilaa (useState) Reactissa tallentamaan käyttäjän syöttämää tietoa ja miten voit käsitellä lomakkeen lähettämistä. Interaktiivisuuden lisääminen lomakkeisiin auttaa käyttäjiä vuorovaikutuksessa sovelluksesi kanssa ja luo paremman käyttäjäkokemuksen.
Jatka harjoittelua ja kokeilua erilaisten interaktiivisten toimintojen kanssa. Seuraavaksi voit syventää taitojasi lisäämällä datan tallennusta tietokantaan, luomalla reagoivia käyttöliittymiä ja lisäämällä animaatioita. Onnea matkaan kohti monipuolista ja interaktiivista web-sovelluskehitystä!
Harjoitus 5: Tiedon Näyttäminen Dynaamisesti ja API-kutsujen Tekeminen
Tässä harjoituksessa luomme dynaamisen sivun, joka näyttää tietoa ulkoisesta API:sta. Käytämme “JSONPlaceholder” -testi-API:ta esimerkkinä.
- Luo uusi kansio “pages” -kansion sisälle nimeltä “posts”.
- Avaa “posts” -kansio ja luo uusi tiedosto nimeltä “index.js”.
- Avaa “index.js” ja kirjoita seuraava koodi:
import React, { useState, useEffect } from 'react';
import Header from '../../components/Header';
function Posts() {
const [posts, setPosts] = useState([]);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts')
.then(response => response.json())
.then(data => setPosts(data))
.catch(error => console.error('Virhe:', error));
}, []);
return (
<div>
<Header />
<h2>Blogipostaukset</h2>
<ul>
{posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}
export default Posts;
- Tallenna tiedosto.
Tässä esimerkissä haemme “JSONPlaceholder” -API:sta blogipostauksia ja näytämme ne sivulla. Käytämme Reactin useState-koukkua tilan hallintaan ja useEffect-koukkua API-kutsun tekemiseen sivun latauksen yhteydessä.
Kun sivu latautuu, se hakee blogipostaukset ulkoisesta API:sta ja näyttää ne sivulla listaamalla postausten otsikot. Käyttäjät voivat nyt nähdä dynaamisen tiedon API-kutsun perusteella.
Tämä esimerkki osoittaa, miten voit tehdä API-kutsuja React-sovelluksissa ja näyttää saadun datan dynaamisesti käyttöliittymässä. Tämä on tärkeä taito, kun rakennat sovelluksia, jotka tarvitsevat ulkoista dataa, kuten uutisia, käyttäjien kommentteja tai tuotteiden tietoja.
Jatka harjoittelua ja kokeilua erilaisten edistyneempien interaktiivisten toimintojen kanssa. Seuraavaksi voit syventää taitojasi käsittelemällä käyttäjätilien hallintaa, toteuttamalla monimutkaisempia API-kutsuja ja luomalla reaaliaikaisia sovelluksia. Onnea matkaan kohti entistä monipuolisempaa web-sovelluskehitystä!
Next.js 13: Back-end Kehitys ja Tietokannat
Kun olet saanut vankan perustan Next.js 13:n front-end-kehityksessä, on aika siirtyä syvemmälle ja tutkia back-end-kehitystä sekä tietokantojen käyttöä. Näiden taitojen avulla voit luoda täysin toimivia ja monipuolisia web-sovelluksia, jotka tarjoavat käyttäjille entistä enemmän ominaisuuksia.
Back-end-kehitys: Serverless-toiminnallisuus ja API-rakentaminen
Next.js 13 tarjoaa integroidun serverless-toiminnallisuuden, joka helpottaa back-end-palveluiden rakentamista ilman monimutkaista infrastruktuuria. Voit luoda omia API-reittejä, jotka käsittelevät tietoa ja tarjoavat palveluita front-end-sovelluksellesi. Tämä mahdollistaa esimerkiksi käyttäjän sisäänkirjautumisen, datan tallentamisen ja käyttäjien toimintojen hallinnan.
Luo ensin uusi “pages” -kansio nimeltä “api”. Avaa “api” -kansio ja luo uusi tiedosto nimeltä “hello.js”. Kirjoita “hello.js” -tiedostoon seuraava koodi:
export default (req, res) => {
res.status(200).json({ message: 'Tervetuloa API-reitille!' });
};
Nyt olet luonut yksinkertaisen API-reitin, joka palauttaa JSON-vastauksen. Voit testata tätä avaamalla selaimen ja siirtymällä osoitteeseen “http://localhost:3000/api/hello“. Näet JSON-vastauksen, jonka viesti on “Tervetuloa API-reitille!”.
Tietokannat: Datan Tallentaminen ja Hallinta
Monet web-sovellukset tarvitsevat tietokantoja datan tallentamiseen ja hallintaan. Next.js 13:ssa voit käyttää erilaisia tietokantoja, kuten SQL- tai NoSQL-tietokantoja, riippuen tarpeistasi. Voit käyttää tietokantoja esimerkiksi käyttäjien tietojen tallentamiseen, blogipostauksien hallintaan tai tuotetietojen säilyttämiseen.
Esimerkkinä käytämme “MongoDB” -tietokantaa. Voit käyttää “mongoose” -kirjastoa yhteyden muodostamiseen ja tietokannan hallintaan.
- Asenna “mongoose” -kirjasto komennolla:
npm install mongoose
- Luo “utils” -kansio projektisi juureen.
- Avaa “utils” -kansio ja luo uusi tiedosto nimeltä “dbConnect.js”. Kirjoita “dbConnect.js” -tiedostoon seuraava koodi:
import mongoose from 'mongoose';
const connection = {};
async function dbConnect() {
if (connection.isConnected) {
return;
}
const db = await mongoose.connect(process.env.MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
});
connection.isConnected = db.connections[0].readyState;
console.log('Tietokanta yhdistetty');
}
export default dbConnect;
Nyt olet luonut yhteyden MongoDB-tietokantaan ja voit käyttää dbConnect-funktiota yhteyden muodostamiseen.
Näiden esimerkkien avulla olet ottanut ensiaskeleita back-end-kehityksessä ja tietokantojen käytössä Next.js 13:ssa. Voit nyt luoda omia API-reittejä ja käyttää tietokantoja luodaksesi monipuolisia ja dynaamisia web-sovelluksia. Jatka oppimista ja kokeilemista syventääksesi taitojasi back-end-kehityksessä ja tietokantojen käytössä!
Harjoitus 6: Tiedon Tallentaminen Tietokantaan Käyttäen API:ta
Tässä harjoituksessa yhdistämme edellisen front-end-tehtävän lomakkeen ja tietokantatoiminnallisuuden. Luomme API-reitin, joka vastaanottaa lomakkeen tiedot ja tallentaa ne MongoDB-tietokantaan.
- Luo uusi kansio “pages” -kansion sisälle nimeltä “api”.
- Avaa “api” -kansio ja luo uusi tiedosto nimeltä “submitForm.js”.
- Avaa “submitForm.js” ja kirjoita seuraava koodi:
import dbConnect from '../../utils/dbConnect';
import FormModel from '../../models/FormModel';
dbConnect();
export default async (req, res) => {
if (req.method === 'POST') {
try {
const { name, email } = req.body;
const formData = new FormModel({ name, email });
await formData.save();
res.status(201).json({ message: 'Tiedot tallennettu onnistuneesti!' });
} catch (error) {
res.status(500).json({ message: 'Tiedon tallentaminen epäonnistui.' });
}
} else {
res.status(405).json({ message: 'Vain POST-pyyntöjä sallitaan.' });
}
};
- Luo kansio “models” projektisi juureen.
- Avaa “models” -kansio ja luo uusi tiedosto nimeltä “FormModel.js”.
- Avaa “FormModel.js” ja kirjoita seuraava koodi:
import mongoose from 'mongoose';
const formSchema = new mongoose.Schema({
name: String,
email: String,
});
const FormModel = mongoose.models.FormModel || mongoose.model('FormModel', formSchema);
export default FormModel;
Nyt olet luonut API-reitin, joka tallentaa lomakkeen tiedot MongoDB-tietokantaan käyttäen “mongoose” -kirjastoa ja “FormModel” -mallia.
Voit testata tätä lomaketta lähettämällä POST-pyynnön esimerkiksi Postman-ohjelmalla tai käyttämällä “fetch” -funktiota front-end-sovelluksessasi. Tämä harjoitus osoittaa, miten voit tallentaa käyttäjän syöttämän tiedon tietokantaan ja luoda monipuolisia toiminnallisuuksia.
Jatka kokeilua ja oppimista, jotta voit luoda entistä monimutkaisempia toiminnallisuuksia ja yhdistää front-end- ja back-end-puolen taitosi luodaksesi kokonaisia web-sovelluksia. Onnea matkaan kohti edistyneempää web-sovelluskehitystä!
Harjoitus 7: Käytännön Esimerkki – Käyttäjien Rekisteröinti ja Kirjautuminen
Tässä harjoituksessa luomme moniulotteisemman esimerkin, jossa yhdistämme front-endin ja back-endin Next.js 13 -projektissa. Luomme käyttäjien rekisteröinti- ja kirjautumistoiminnallisuuden käyttäen MongoDB-tietokantaa ja bcrypt-salausta.
- Luo “pages” -kansioon kansio nimeltä “auth”.
- Avaa “auth” -kansio ja luo tiedosto nimeltä “register.js”.
- Avaa “register.js” ja kirjoita seuraava koodi:
import dbConnect from '../../utils/dbConnect';
import UserModel from '../../models/UserModel';
import bcrypt from 'bcrypt';
dbConnect();
export default async (req, res) => {
if (req.method === 'POST') {
try {
const { username, password } = req.body;
// Tarkista, onko käyttäjänimi jo käytössä
const existingUser = await UserModel.findOne({ username });
if (existingUser) {
return res.status(400).json({ message: 'Käyttäjänimi on jo käytössä.' });
}
// Salasanan salaaminen bcryptillä
const hashedPassword = await bcrypt.hash(password, 10);
// Tallenna uusi käyttäjä tietokantaan
const newUser = new UserModel({ username, password: hashedPassword });
await newUser.save();
res.status(201).json({ message: 'Rekisteröinti onnistui!' });
} catch (error) {
res.status(500).json({ message: 'Rekisteröinti epäonnistui.' });
}
} else {
res.status(405).json({ message: 'Vain POST-pyyntöjä sallitaan.' });
}
};
- Luo “login.js” -tiedosto “auth” -kansioon ja kirjoita siihen seuraava koodi:
import dbConnect from '../../utils/dbConnect';
import UserModel from '../../models/UserModel';
import bcrypt from 'bcrypt';
dbConnect();
export default async (req, res) => {
if (req.method === 'POST') {
try {
const { username, password } = req.body;
// Etsi käyttäjä tietokannasta
const user = await UserModel.findOne({ username });
if (!user) {
return res.status(404).json({ message: 'Käyttäjää ei löytynyt.' });
}
// Vertaa salasanoja bcryptin avulla
const passwordMatch = await bcrypt.compare(password, user.password);
if (!passwordMatch) {
return res.status(401).json({ message: 'Väärä salasana.' });
}
res.status(200).json({ message: 'Kirjautuminen onnistui!' });
} catch (error) {
res.status(500).json({ message: 'Kirjautuminen epäonnistui.' });
}
} else {
res.status(405).json({ message: 'Vain POST-pyyntöjä sallitaan.' });
}
};
- Luo “models” -kansioon “UserModel.js” -tiedosto ja kirjoita siihen seuraava koodi:
import mongoose from 'mongoose';
const userSchema = new mongoose.Schema({
username: String,
password: String,
});
const UserModel = mongoose.models.UserModel || mongoose.model('UserModel', userSchema);
export default UserModel;
Tässä esimerkissä olemme luoneet moniulotteisen käyttäjien rekisteröinti- ja kirjautumistoiminnallisuuden. Voit nyt rekisteröityä uudeksi käyttäjäksi antamalla käyttäjänimen ja salasanan, jotka tallennetaan salattuina tietokantaan. Voit myös kirjautua sisään antamalla käyttäjänimen ja salasanan ja verrata niitä tietokannassa tallennettuihin salattuihin salasanoihin.
Tämä harjoitus osoittaa, miten Next.js 13:n avulla voit yhdistää front-endin ja back-endin luomalla monimutkaisempia toiminnallisuuksia, kuten käyttäjänhallintaa ja autentikointia. Jatka oppimista ja kokeilua yhdistääksesi erilaisia ominaisuuksia ja luodaksesi monipuolisia ja turvallisia web-sovelluksia!
Harjoitus 8: Käyttäjäpeli ja Tulosten Tallentaminen
Tässä harjoituksessa toteutamme yksinkertaisen tietovisa-pelin, jossa käyttäjä voi vastata kysymyksiin ja ansaita pisteitä. Pelin tulokset tallennetaan tietokantaan ja näytetään ruudulla korkeimmasta pistemäärästä alkaen.
- Luo “pages” -kansioon kansio nimeltä “game”.
- Avaa “game” -kansio ja luo tiedosto nimeltä “quiz.js”.
- Avaa “quiz.js” ja kirjoita seuraava koodi:
import { useState } from 'react';
import Header from '../../components/Header';
import dbConnect from '../../utils/dbConnect';
import GameResultModel from '../../models/GameResultModel';
dbConnect();
const questions = [
{
question: 'Mikä on pääkaupunki Ranskassa?',
options: ['Lontoo', 'Pariisi', 'Berliini', 'Rooma'],
correctAnswer: 'Pariisi',
},
{
question: 'Kuinka monta planeettaa on aurinkokunnassamme?',
options: ['5', '8', '9', '12'],
correctAnswer: '8',
},
// Lisää lisää kysymyksiä tähän
];
export default function Quiz() {
const [score, setScore] = useState(0);
const [currentQuestion, setCurrentQuestion] = useState(0);
const [showResult, setShowResult] = useState(false);
const handleAnswer = (selectedOption) => {
if (selectedOption === questions[currentQuestion].correctAnswer) {
setScore(score + 1);
}
if (currentQuestion + 1 < questions.length) {
setCurrentQuestion(currentQuestion + 1);
} else {
saveGameResult();
setShowResult(true);
}
};
const saveGameResult = async () => {
const newGameResult = new GameResultModel({ score });
await newGameResult.save();
};
return (
<div>
<Header />
{showResult ? (
<div>
<h2>Pelitulokset</h2>
<p>Pistemääräsi: {score}</p>
</div>
) : (
<div>
<h2>Tietovisa</h2>
<p>Kysymys {currentQuestion + 1}: {questions[currentQuestion].question}</p>
{questions[currentQuestion].options.map((option, index) => (
<button key={index} onClick={() => handleAnswer(option)}>
{option}
</button>
))}
</div>
)}
</div>
);
}
- Luo “models” -kansioon “GameResultModel.js” -tiedosto ja kirjoita siihen seuraava koodi:
import mongoose from 'mongoose';
const gameResultSchema = new mongoose.Schema({
score: Number,
timestamp: { type: Date, default: Date.now },
});
const GameResultModel = mongoose.models.GameResultModel || mongoose.model('GameResultModel', gameResultSchema);
export default GameResultModel;
Nyt olet luonut yksinkertaisen tietovisa-pelin, jossa käyttäjä voi vastata kysymyksiin ja ansaita pisteitä. Pelin tulokset tallennetaan tietokantaan GameResultModel-mallin avulla. Voit myös muokata questions-taulukkoa lisäämällä lisää kysymyksiä.
Kun käyttäjä on suorittanut pelin, näytetään tulosruutu, joka näyttää käyttäjän pistemäärän. Voit jatkaa tätä esimerkkiä luomalla käyttäjänhallinnan, pisteiden järjestämisen ja jopa lisäämällä enemmän toiminnallisuutta peliin, kuten aikarajan ja vaikeustason.
Tämä esimerkki osoittaa, miten voit yhdistää käyttäjänhallinnan, pelillisen toiminnallisuuden ja tulosten tallentamisen tietokantaan Next.js 13 -projektissa. Jatka oppimista ja kokeilua luodaksesi entistä monipuolisempia ja hauskempia web-sovelluksia.
Harjoitus 8: Käyttäjäpeli ja Tulosten Tallentaminen (jatkoa)
Kun olet luonut perustan tietovisa-pelille ja tulosten tallentamiselle, voit edelleen syventää toiminnallisuutta ja parantaa käyttäjäkokemusta. Tässä jatkamme esimerkkiä ja lisäämme peliin käyttäjänhallinnan sekä pistetulosten järjestämisen.
- Luo uusi “pages” -kansioon kansio nimeltä “leaderboard”.
- Avaa “leaderboard” -kansio ja luo tiedosto nimeltä “index.js”.
- Avaa “index.js” ja kirjoita seuraava koodi:
import Header from '../../components/Header';
import dbConnect from '../../utils/dbConnect';
import GameResultModel from '../../models/GameResultModel';
dbConnect();
export default function Leaderboard({ results }) {
return (
<div>
<Header />
<h2>Pelitulosten Top 10</h2>
<ol>
{results.map((result, index) => (
<li key={index}>{result.score}</li>
))}
</ol>
</div>
);
}
export async function getServerSideProps() {
const results = await GameResultModel.find()
.sort({ score: -1 })
.limit(10)
.exec();
return { props: { results: JSON.parse(JSON.stringify(results)) } };
}
- Avaa “components” -kansioon “Header.js” -tiedosto ja lisää seuraava linkki:
<Link href="/leaderboard">
<a>Top 10 Pelitulokset</a>
</Link>
Nyt olet luonut “Leaderboard” -sivun, joka näyttää kymmenen parasta pelitulosta järjestettynä pisteiden mukaan. Voit navigoida tähän sivulle “Top 10 Pelitulokset” -linkin kautta, jonka lisäsit “Header.js” -tiedostoon.
Tämä esimerkki jatkaa edellistä tietovisa-peliä lisäämällä pistetulosten järjestämisen ja näyttämisen. Käyttäjät voivat nyt kilpailla keskenään saadakseen korkeimman pistemäärän ja nähdäkseen sijoituksensa tulostaulukossa.
Jatka tätä esimerkkiä lisäämällä käyttäjänhallintaa, kuten kirjautumisen ja rekisteröinnin varmistaminen ennen peliin pääsyä. Voit myös laajentaa peliä lisäämällä uusia kysymyksiä ja toiminnallisuuksia.
Tämä esimerkki osoittaa, miten voit yhdistää käyttäjänhallinnan, pelillisen toiminnallisuuden ja tulosten tallentamisen monipuoliseksi web-sovellukseksi Next.js 13 -projektissa. Jatka oppimista ja kokeilua, ja luo omia innovatiivisia ja viihdyttäviä toiminnallisuuksia!
Harjoitus 8: Käyttäjäpeli ja Tulosten Tallentaminen (jatkoa)
Jatketaan vielä tätä esimerkkiä lisäämällä käyttäjänhallintaa, joka varmistaa, että käyttäjät ovat kirjautuneina pelatessaan ja tallentavat pelituloksensa.
- Luo “pages” -kansioon kansio nimeltä “auth”.
- Avaa “auth” -kansio ja luo tiedosto nimeltä “loginRequired.js”.
- Avaa “loginRequired.js” ja kirjoita seuraava koodi:
import { useSession } from 'next-auth/react';
export default function LoginRequired({ children }) {
const { data: session } = useSession();
if (!session) {
return <p>Kirjaudu sisään pelataksesi.</p>;
}
return children;
}
- Avaa “quiz.js” ja muokkaa komponentin tuontia ja lisää “LoginRequired” -komponentti ympärille:
import { useState } from 'react';
import Header from '../../components/Header';
import dbConnect from '../../utils/dbConnect';
import GameResultModel from '../../models/GameResultModel';
import { useSession } from 'next-auth/react';
import LoginRequired from '../auth/loginRequired';
// ... aikaisempi koodi ...
export default function Quiz() {
// ... aikaisempi koodi ...
return (
<div>
<Header />
<LoginRequired>
{showResult ? (
<div>
<h2>Pelitulokset</h2>
<p>Pistemääräsi: {score}</p>
</div>
) : (
<div>
<h2>Tietovisa</h2>
<p>Kysymys {currentQuestion + 1}: {questions[currentQuestion].question}</p>
{questions[currentQuestion].options.map((option, index) => (
<button key={index} onClick={() => handleAnswer(option)}>
{option}
</button>
))}
</div>
)}
</LoginRequired>
</div>
);
}
Nyt olemme lisänneet käyttäjänhallinnan “LoginRequired” -komponentin avulla, joka tarkistaa, onko käyttäjä kirjautunut sisään ennen kuin näytetään pelisivu. Jos käyttäjä ei ole kirjautunut sisään, he näkevät viestin “Kirjaudu sisään pelataksesi.”
Tämä viimeinen osa esimerkkiä korostaa, miten voit yhdistää käyttäjänhallinnan, pelillisen toiminnallisuuden ja tulosten tallentamisen monipuoliseksi web-sovellukseksi Next.js 13 -projektissa. Käyttäjät voivat nyt pelata peliä kirjautumisen jälkeen, ja heidän tuloksensa tallentuvat tietokantaan.
Jatka tätä esimerkkiä laajentamalla sitä omilla ideoillasi ja toiminnallisuuksillasi. Voit esimerkiksi lisätä erilaisia kysymyksiä, palkintoja tai pelimuotoja. Onnea matkaan kohti monipuolista ja viihdyttävää web-sovelluskehitystä!
Harjoitus 8: Käyttäjäpeli ja Tulosten Tallentaminen (jatkoa)
Viimeistellään vielä tämä esimerkki lisäämällä pelille hieman visuaalista ilmettä CSS:n ja stylingin avulla.
- Luo “styles” -kansio projektisi juureen.
- Avaa “styles” -kansio ja luo tiedosto nimeltä “quiz.module.css”.
- Avaa “quiz.module.css” ja lisää seuraava CSS-koodi:
.quiz-container {
max-width: 400px;
margin: 0 auto;
padding: 20px;
border: 2px solid #ccc;
border-radius: 8px;
}
.question {
font-size: 18px;
margin-bottom: 10px;
}
.options {
display: grid;
grid-gap: 10px;
}
.option {
background-color: #f0f0f0;
border: 2px solid #ddd;
border-radius: 6px;
padding: 10px;
cursor: pointer;
transition: background-color 0.3s, border-color 0.3s;
}
.option:hover {
background-color: #ddd;
border-color: #ccc;
}
.result {
font-size: 24px;
text-align: center;
margin-top: 20px;
}
- Avaa “quiz.js” ja lisää “className” -ominaisuudet komponenttien JSX:ään:
// ... aikaisempi koodi ...
export default function Quiz() {
// ... aikaisempi koodi ...
return (
<div className={styles.quizContainer}>
<Header />
<LoginRequired>
{showResult ? (
<div>
<h2 className={styles.result}>Pelitulokset</h2>
<p className={styles.result}>Pistemääräsi: {score}</p>
</div>
) : (
<div>
<h2 className={styles.question}>Kysymys {currentQuestion + 1}: {questions[currentQuestion].question}</h2>
<div className={styles.options}>
{questions[currentQuestion].options.map((option, index) => (
<button key={index} className={styles.option} onClick={() =>
handleAnswer(option)}>
{option}
</button>
))}
</div>
</div>
)}
</LoginRequired>
</div>
);
}
Nyt olet lisännyt stylingin pelikomponenttiin käyttämällä CSS-moduulia. Tämä tekee pelistä visuaalisesti houkuttelevamman ja helpottaa käyttäjän navigointia ja interaktiota.
Tämä viimeinen osa esimerkkiä korostaa, miten voit parantaa käyttäjäkokemusta lisäämällä visuaalista ilmettä ja stylingia pelisivulle. Voit jatkaa tätä esimerkkiä lisäämällä vielä enemmän visuaalisia parannuksia ja harkita animaatioita ja graafisia elementtejä.
Nyt olet luonut monipuolisen tietovisa-pelin, joka sisältää käyttäjänhallinnan, pelillisen toiminnallisuuden, tulosten tallentamisen tietokantaan sekä visuaalisen ilmeen. Onnea matkaan kohti omien innovatiivisten ja viihdyttävien web-sovellusten luomista Next.js 13 -projektissa!
Harjoitus 8: Käyttäjäpeli ja Tulosten Tallentaminen (viimeinen osa)
Lopuksi, voimme vielä lisätä käyttäjälle mahdollisuuden katsoa omia pelituloksiaan kirjautumisen jälkeen.
- Luo “pages” -kansioon kansio nimeltä “profile”.
- Avaa “profile” -kansio ja luo tiedosto nimeltä “index.js”.
- Avaa “index.js” ja kirjoita seuraava koodi:
import { useSession } from 'next-auth/react';
import Header from '../../components/Header';
import dbConnect from '../../utils/dbConnect';
import GameResultModel from '../../models/GameResultModel';
dbConnect();
export default function Profile({ userResults }) {
const { data: session } = useSession();
return (
<div>
<Header />
<h2>Oma Profiili</h2>
<p>Kirjautunut käyttäjänä: {session.user.email}</p>
<h3>Pelitulokset</h3>
{userResults.length === 0 ? (
<p>Ei pelituloksia vielä.</p>
) : (
<ul>
{userResults.map((result, index) => (
<li key={index}>Pisteet: {result.score}</li>
))}
</ul>
)}
</div>
);
}
export async function getServerSideProps(context) {
const session = await getSession(context);
if (!session) {
return {
redirect: {
destination: '/auth/login',
permanent: false,
},
};
}
const userResults = await GameResultModel.find({ user: session.user.email })
.sort({ score: -1 })
.exec();
return { props: { userResults: JSON.parse(JSON.stringify(userResults)) } };
}
Tämä “Profile” -sivu näyttää käyttäjän omat pelitulokset kirjautumisen jälkeen. Käyttäjä voi nähdä, miten he ovat suoriutuneet aiemmissa peleissä.
Tämä viimeinen lisäys esimerkkiin tarjoaa käyttäjälle mahdollisuuden tarkastella ja seurata omia pelituloksiaan. Voit jatkaa tätä esimerkkiä lisäämällä vielä enemmän käyttäjäkohtaisia toiminnallisuuksia, kuten saavutuksia tai muokattavia profiilitietoja.
Tämä esimerkki osoittaa, miten voit luoda monimutkaisen web-sovelluksen Next.js 13 -projektissa yhdistämällä käyttäjänhallinnan, pelillisen toiminnallisuuden, tulosten tallentamisen tietokantaan, visuaalisen ilmeen sekä käyttäjäkohtaisen sisällön. Jatka oppimista ja kehitystyötäsi rakentamalla omia uniikkeja ja monipuolisia web-sovelluksia!
Sovelluksen viimeistely ja julkaisu
Voit helposti julkaista Next.js 13 -projektisi GitHub-repositoriosta ja Vercel-pilvipalvelusta. Tässä on vaiheet: (Käydään tätä paremmin läpi, blogisarjan seuraavissa osissa. Github-desktop apuohjelman avulla tämä käy helposti.)
GitHub-repositorion Luominen:
- Luo GitHub-tili, jos sinulla ei ole vielä sellaista.
- Kirjaudu GitHubiin ja mene profiilisi yläreunassa olevaan “+”-valikkoon ja valitse “New repository” (Uusi repositorio).
- Anna repositoriollesi nimi, valitse sopiva näkyvyystaso ja muut asetukset.
- Voit valita repositorion olevan julkinen tai yksityinen, riippuen siitä, kuka saa nähdä koodisi.
Sovelluksen Julkaiseminen GitHubiin:
- Voit ladata projektisi koodin GitHub-repositorioosi käyttäen Git-versionhallintaa. Tämä voidaan tehdä komentoriviltä seuraavilla komennoilla:
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin <GitHub-repository-URL>
git push -u origin main
Vercel-tilin Luominen:
- Luo Vercel-tili, jos sinulla ei ole sellaista.
- Kirjaudu Verceliin ja valitse “New Project” (Uusi projekti).
- Yhdistä GitHub-tilisi Vercel-tiliisi ja valitse repositoriosi.
Sovelluksen Julkaiseminen Vercelissä:
- Kun olet yhdistänyt repositorion, Vercel hakee automaattisesti projektitiedot ja asetukset.
- Voit konfiguroida julkaisuasetuksia, kuten määrittää “Production” ja “Preview” -ympäristöt.
- Kun olet valmis, voit aloittaa julkaisun napsauttamalla “Deploy” (Julkaise).
Vercel aloittaa automaattisen julkaisuprosessin. Se luo julkaisun sekä “Production”-ympäristöön että mahdollisesti “Preview”-ympäristöön, jos olet määrittänyt sellaisen. Voit seurata julkaisun etenemistä Vercelin hallintapaneelissa.
Kun julkaisu on valmis, saat Verceliltä osoitteen, jossa sovelluksesi on julkaistu. Voit jakaa tämän osoitteen muille ja nähdä sovelluksesi toimivan reaaliajassa.
Tämä on perusprosessi sovelluksen julkaisemiselle GitHubin ja Vercelin avulla. Muista, että nämä palvelut tarjoavat lisää konfiguraatio- ja mukautusmahdollisuuksia, joten voit syventyä niihin tarpeen mukaan. Onnea julkaisuun!