Přesunutí stavu výš

Festivalová aplikace se teď skládá z komponent: nahoře je Hlavicka a pro každou kapelu jedna KartaKapely. Každá karta má tlačítko s hvězdou a ve vlastním stavu si drží, jestli je její kapela oblíbená, jak jste to viděli v lekci Stav. Teď má hlavička ukázat, kolik je oblíbených kapel. Jenže to nejde: stav je uvnitř karet a komponenta nemůže číst stav jiné komponenty. Props vedou jen jedním směrem, dolů od rodiče k jeho dětem.

Když dvě komponenty potřebují stejný stav, přesuňte ho výš, do jejich nejbližšího společného rodiče: do nejbližší komponenty, která má obě uvnitř. Tady je to App. Stav bude v App a ta každému dítěti předá v props, co potřebuje: hodnotu a funkci, která ji mění. Tomu se říká přesunout stav výš (anglicky lifting state up).

Malý příklad, se dvěma komponentami v jednom souboru: košík ukazuje koupené vstupenky a tlačítko pod ním koupí další:

import { useState } from "react";

export default function App() {
    const [vstupenky, setVstupenky] = useState(0);

    function kup() {
        setVstupenky((vstupenky) => vstupenky + 1);
    }

    return (
        <main>
            <Kosik vstupenky={vstupenky} />
            <TlacitkoKoupit onKoupit={kup} />
        </main>
    );
}

function Kosik({ vstupenky }) {
    return <p>Vstupenky v košíku: {vstupenky}</p>;
}

function TlacitkoKoupit({ onKoupit }) {
    return <button onClick={onKoupit}>Koupit vstupenku</button>;
}

TlacitkoKoupit neví, co koupení udělá. Jen zavolá onKoupit, když se na něj klikne. App rozhodne, co se stane, změní svůj stav a vykreslí se znovu, takže Kosik dostane v props nové číslo. Stav je na jednom místě a obě děti používají stejnou hodnotu.

U oblíbených kapel si App drží pole s id oblíbených kapel. Každá karta dostane dvě props: oblibena, jestli je její kapela v poli, a onPrepnoutOblibenou, funkci, která kapelu do pole přidá, nebo ji z něj odebere. Nové pole vzniká ze starého, takže ho v obou větvích vytvoří aktualizační funkce:

function prepniOblibenou(id) {
    if (oblibene.includes(id)) {
        setOblibene((oblibene) =>
            oblibene.filter((oblibenaId) => oblibenaId !== id),
        );
    } else {
        setOblibene((oblibene) => [...oblibene, id]);
    }
}

onPrepnoutOblibenou={() => prepniOblibenou(kapela.id)} dá každé kartě funkci, která už svou kapelu zná, stejně jako v lekci Události. A karta už useState nepotřebuje: ukazuje, co říkají její props, a když se klikne na hvězdu, zavolá onPrepnoutOblibenou.

Pokyny

V App mějte oblíbené kapely ve stavové proměnné oblibene: v poli s id, které začíná prázdné. Každé komponentě KartaKapely předejte props oblibena a onPrepnoutOblibenou a v KartaKapely.jsx je použijte místo vlastního stavu karty.

Předejte komponentě Hlavicka počet oblíbených kapel jako pocet. Vyzkoušejte to: označte hvězdou pár kapel.

Začněte programovat zdarma

Registrací souhlasíte s provozními podmínkami a zásadami ochrany osobních údajů.

Nebo se registrujte pomocí:

Zpět

1/6

Další