⚛️ React

Jifunze React.js — JavaScript library maarufu kwa ajili ya kuunda user interfaces. Components, hooks, state management, na modern web apps.

English / Kiswahili • Intermediate • Text + Code Examples

📋 Yaliyomo — Table of Contents

  1. React ni nini? / What is React?
  2. Kuweka React / Setup na Vite
  3. JSX — JavaScript XML
  4. Components — Vipengele
  5. Props — Kupitisha Data
  6. State — Hali ya Component
  7. useState Hook
  8. useEffect Hook
  9. Conditional Rendering
  10. Lists na Keys
  11. Forms kwenye React
  12. React Router
  13. Project: Msimu wa Hali ya Hewa
  14. Project: Contact Manager

1. React ni nini? / What is React?

Modern JavaScript library kwa ajili ya UI

🇹🇿 Kiswahili: React ni library ya JavaScript iliyoundwa na Meta (Facebook) kwa ajili ya kuunda user interfaces. React inakuwezesha kugawanya UI yako katika components — vipande vidogo vidogo vya code vinavyoweza kutumika tena.

🇬🇧 English: React is a JavaScript library created by Meta (Facebook) for building user interfaces. React lets you break down your UI into components — small, reusable pieces of code.

💡 Kwa nini React? Inatumika na makampuni makubwa (Facebook, Netflix, Airbnb, WhatsApp). Ina community kubwa. React code ni rahisi kudumisha na kujaribu.

2. Kuweka React / Setup na Vite

Anzisha project yako ya kwanza ya React

# Hakikisha una Node.js (nodejs.org)
# Fungua terminal na endesha:

# Create React App (njia moja — polepole lakini imara)
npx create-react-app project-yangu

# Vite (njia ya kisasa — haraka sana) — RECOMMENDED!
npm create vite@latest project-yangu -- --template react
cd project-yangu
npm install
npm run dev

Baada ya kukimbia npm run dev, fungua browser kwenye http://localhost:5173 — utaona React app yako!

⚡ Tip: Vite ni ya haraka zaidi kuliko Create React App. Tumia Vite kwa projects mpya.

3. JSX — JavaScript XML

Andika HTML ndani ya JavaScript

🇹🇿 Kiswahili: JSX inakuruhusu kuandika HTML moja kwa moja kwenye JavaScript code. Inaonekana kama HTML lakini ni JavaScript.

function App() {
    const jina = "Juma";
    const umri = 25;

    return (
        <div>
            <h1>Habari, {jina}!</h1>
            <p>Una miaka {umri}.</p>
            <p>Mara mbili ya umri wako: {umri * 2}</p>
        </div>
    );
}

export default App;
💡 JSX Rules:
  • Return moja element mama — tumia <div> au <>...</> (Fragment)
  • class inakuwa className
  • Tumia { } kuingiza JavaScript expressions
  • Self-closing tags: <img />

4. Components — Vipengele

Gawanya UI yako kwa sehemu ndogo

Component ni kitendakazi cha JavaScript kinachorudisha JSX. Kila component inaweza kutumika tena na tena.

// Header.jsx — component moja
function Header() {
    return (
        <header>
            <h1>Karibu kwenye Tovuti Yangu</h1>
            <nav>
                <a href="#">Nyumbani</a>
                <a href="#">Kuhusu</a>
            </nav>
        </header>
    );
}

export default Header;

// App.jsx — component kuu
import Header from "./Header";
import Footer from "./Footer";

function App() {
    return (
        <div>
            <Header />
            <main>
                <p>Hii ni sehemu kuu ya ukurasa.</p>
            </main>
            <Footer />
        </div>
    );
}

export default App;
⚡ Tip: Kila component inapaswa kufanya kazi moja tu. Ikiwa component inakuwa kubwa, gawanya!

5. Props — Kupitisha Data

Tuma data kutoka component mama kwenda component mtoto

// Mzazi anayetuma props
function App() {
    return (
        <div>
            <Salamu jina="Juma" umri={25} />
            <Salamu jina="Aisha" umri={22} />
        </div>
    );
}

// Component inayopokea props
function Salamu(props) {
    return (
        <div>
            <h2>Habari, {props.jina}!</h2>
            <p>Umri: {props.umri}</p>
        </div>
    );
}

// Njia ya kisasa — destructuring
function Salamu({ jina, umri }) {
    return (
        <div>
            <h2>Habari, {jina}!</h2>
            <p>Umri: {umri}</p>
        </div>
    );
}

6. State — Hali ya Component

Data inayobadilika kwenye component

🇹🇿 Kiswahili: Props hazibadiliki (immutable) kutoka kwa component mtoto. Ikiwa unataka data ibadilike, unahitaji state.

🇬🇧 English: Props are read-only from the child component. If you want data that changes over time, you need state.

import { useState } from "react";

function Counter() {
    const [count, setCount] = useState(0);
    // count = thamani ya sasa
    // setCount = kitendakazi cha kubadilisha thamani

    return (
        <div>
            <p>Umebonyeza mara: {count}</p>
            <button onClick={() => setCount(count + 1)}>
                Bonyeza mimi
            </button>
            <button onClick={() => setCount(0)}>
                Weka upya
            </button>
        </div>
    );
}

7. useState Hook — Kina Zaidi

Hali na mwingiliano wa watumiaji

State yenye Object

function Profile() {
    const [mtu, setMtu] = useState({
        jina: "Juma",
        umri: 25,
        kazi: "Developer"
    });

    const badilishaKazi = () => {
        setMtu({ ...mtu, kazi: "Designer" });
        // Tuma ... spread operator kuweka data iliyobaki
    };

    return (
        <div>
            <p>{mtu.jina} — {mtu.kazi}</p>
            <button onClick={badilishaKazi}>Badilisha Kazi</button>
        </div>
    );
}

State yenye Array

function TodoList() {
    const [tasks, setTasks] = useState(["Jifunze React"]);

    const ongezaTask = () => {
        setTasks([...tasks, "Task mpya"]);
    };

    const futaTask = (index) => {
        setTasks(tasks.filter((_, i) => i !== index));
    };

    return (
        <div>
            {tasks.map((task, i) => (
                <p key={i} onClick={() => futaTask(i)}>
                    {task}
                </p>
            ))}
            <button onClick={ongezaTask}>Ongeza Task</button>
        </div>
    );
}
💡 Important: Usibadilishe state moja kwa moja! Tumia setState daima. Kwa objects na arrays, tumia spread operator au map/filter kufanya copy.

8. useEffect Hook

Kufanya kitu baada ya component ku render

🇹🇿 Kiswahili: useEffect inakuwezesha kufanya side effects — kama kupata data kutoka API, ku update title ya browser, au kusikiliza events.

import { useState, useEffect } from "react";

function DataFetcher() {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        // Code hii inaendesha mara moja baada ya component ku render
        fetch("https://api.github.com/users/shbnsemeni")
            .then(res => res.json())
            .then(data => {
                setData(data);
                setLoading(false);
            });
    }, []);  // [] = dependency array — inaendesha mara moja tu

    if (loading) return <p>Inapakia...</p>;

    return (
        <div>
            <h2>{data.login}</h2>
            <p>Followers: {data.followers}</p>
        </div>
    );
}

Dependency Array

// Inaendesha mara moja (mount) tu
useEffect(() => {}, []);

// Inaendesha kila wakati 'count' inabadilika
useEffect(() => {
    document.title = `Umebonyeza mara ${count}`;
}, [count]);

// Inaendesha kila render (epuka!)
useEffect(() => {});

// Cleanup (k.m. kuondoa event listener)
useEffect(() => {
    window.addEventListener("scroll", handleScroll);
    return () => {
        window.removeEventListener("scroll", handleScroll);
    };
}, []);

9. Conditional Rendering

Onyesha vitu tofauti kulingana na hali

function Greeting({ isLoggedIn }) {
    // Ternary — njia ya kawaida
    return (
        <div>
            {isLoggedIn
                ? <h1>Karibu tena!</h1>
                : <h1>Tafadhali ingia</h1>
            }
        </div>
    );
}

function Notification({ messages }) {
    // AND (&&) operator
    return (
        <div>
            {messages.length > 0 && (
                <p>Una ujumbe {messages.length} mpya</p>
            )}
            {messages.length === 0 && (
                <p>Hakuna ujumbe mpya</p>
            )}
        </div>
    );
}

function UserStatus({ role }) {
    // if/else kwenye component
    if (role === "admin") {
        return <p>Una ruhusa za admin</p>;
    } else if (role === "user") {
        return <p>Mtumiaji wa kawaida</p>;
    } else {
        return <p>Mgeni</p>;
    }
}

10. Lists na Keys

Onyesha orodha za data kwenye React

function StudentList() {
    const wanafunzi = [
        { id: 1, jina: "Juma", darasa: "Form 4" },
        { id: 2, jina: "Aisha", darasa: "Form 5" },
        { id: 3, jina: "Baraka", darasa: "Form 6" }
    ];

    return (
        <ul>
            {wanafunzi.map(msomi => (
                <li key={msomi.id}>
                    {msomi.jina} — {msomi.darasa}
                </li>
            ))}
        </ul>
    );
}

// Component tofauti kwa kila item
function StudentItem({ msomi }) {
    return (
        <div className="card">
            <h3>{msomi.jina}</h3>
            <p>Darasa: {msomi.darasa}</p>
        </div>
    );
}

function StudentGrid() {
    const wanafunzi = [...];
    return (
        <div className="grid">
            {wanafunzi.map(m => (
                <StudentItem key={m.id} msomi={m} />
            ))}
        </div>
    );
}
⚡ Tip: key lazima iwe unique na stable. Usitumie index ya array kama key ikiwa orodha inaweza kubadilika (kuongezwa/kufutwa).

11. Forms kwenye React

Kukusanya data kutoka kwa mtumiaji

import { useState } from "react";

function ContactForm() {
    const [form, setForm] = useState({
        jina: "",
        email: "",
        ujumbe: ""
    });

    const handleChange = (e) => {
        const { name, value } = e.target;
        setForm({ ...form, [name]: value });
    };

    const handleSubmit = (e) => {
        e.preventDefault();
        alert(`Asante ${form.jina}! Ujumbe wako umetumwa.`);
        console.log(form);
    };

    return (
        <form onSubmit={handleSubmit}>
            <input
                name="jina"
                value={form.jina}
                onChange={handleChange}
                placeholder="Jina lako"
                required
            />
            <input
                name="email"
                type="email"
                value={form.email}
                onChange={handleChange}
                placeholder="Email yako"
            />
            <textarea
                name="ujumbe"
                value={form.ujumbe}
                onChange={handleChange}
                placeholder="Ujumbe wako"
            />
            <button type="submit">Tuma</button>
        </form>
    );
}
💡 Controlled Components: Katika React, form input ina value inayodhibitiwa na state. Hii inaitwa "controlled component" — React ndio chanzo cha ukweli (single source of truth).

12. React Router

Navigation kati ya kurasa tofauti

// Kwanza: npm install react-router-dom

import { BrowserRouter, Routes, Route, Link } from "react-router-dom";

function Home() {
    return <h1>Nyumbani</h1>;
}
function About() {
    return <h1>Kuhusu Sisi</h1>;
}
function Contact() {
    return <h1>Wasiliana Nasi</h1>;
}

function App() {
    return (
        <BrowserRouter>
            <nav>
                <Link to="/">Nyumbani</Link>
                <Link to="/about">Kuhusu</Link>
                <Link to="/contact">Wasiliana</Link>
            </nav>

            <Routes>
                <Route path="/" element={<Home />} />
                <Route path="/about" element={<About />} />
                <Route path="/contact" element={<Contact />} />
            </Routes>
        </BrowserRouter>
    );
}

useParams — Dynamic Routes

// App.jsx
<Route path="/mwanafunzi/:id" element={<StudentProfile />} />

// StudentProfile.jsx
import { useParams } from "react-router-dom";

function StudentProfile() {
    const { id } = useParams();
    return <h1>Mwanafunzi #{id}</h1>;
}
⚡ Tip: Tumia <Link> badala ya <a> — inazuia page reload na inafanya navigation iwe haraka.

13. Project: Msimu wa Hali ya Hewa

Weather App kwa kutumia API

import { useState, useEffect } from "react";

function WeatherApp() {
    const [mji, setMji] = useState("Dar es Salaam");
    const [hali, setHali] = useState(null);
    const [loading, setLoading] = useState(false);

    const pataHali = async () => {
        setLoading(true);
        try {
            const res = await fetch(
                `https://api.weatherapi.com/v1/current.json?key=YOUR_KEY&q=${mji}`
            );
            const data = await res.json();
            setHali(data);
        } catch (error) {
            alert("Tatizo la kupata data ya hali ya hewa");
        }
        setLoading(false);
    };

    return (
        <div className="weather">
            <h2>Hali ya Hewa</h2>
            <input
                value={mji}
                onChange={(e) => setMji(e.target.value)}
                placeholder="Ingiza jina la mji"
            />
            <button onClick={pataHali}>Tafuta</button>

            {loading && <p>Inatafuta...</p>}
            {hali && (
                <div>
                    <h3>{hali.location.name}, {hali.location.country}</h3>
                    <p>Joto: {hali.current.temp_c}°C</p>
                    <p>Hali: {hali.current.condition.text}</p>
                </div>
            )}
        </div>
    );
}
💡 Note: Pata free API key kutoka weatherapi.com. Usiweke API key moja kwa moja kwenye code kwa production — tumia environment variables.

14. Project: Contact Manager

Programu ya kusimamia anwani za watu

import { useState } from "react";

function ContactManager() {
    const [contacts, setContacts] = useState([]);
    const [form, setForm] = useState({
        jina: "", simu: "", email: ""
    });

    const handleChange = (e) => {
        setForm({ ...form, [e.target.name]: e.target.value });
    };

    const ongeza = (e) => {
        e.preventDefault();
        if (!form.jina || !form.simu) return;
        setContacts([...contacts, { ...form, id: Date.now() }]);
        setForm({ jina: "", simu: "", email: "" });
    };

    const futa = (id) => {
        setContacts(contacts.filter(c => c.id !== id));
    };

    return (
        <div>
            <h2>Simamia Anwani</h2>
            <form onSubmit={ongeza}>
                <input name="jina" value={form.jina}
                    onChange={handleChange} placeholder="Jina" />
                <input name="simu" value={form.simu}
                    onChange={handleChange} placeholder="Namba ya simu" />
                <input name="email" value={form.email}
                    onChange={handleChange} placeholder="Email" />
                <button type="submit">Hifadhi</button>
            </form>

            <h3>Anwani zako ({contacts.length})</h3>
            {contacts.map(c => (
                <div key={c.id} className="contact-card">
                    <h4>{c.jina}</h4>
                    <p>📞 {c.simu}</p>
                    {c.email && <p>✉️ {c.email}</p>}
                    <button onClick={() => futa(c.id)}>Futa</button>
                </div>
            ))}
        </div>
    );
}
⚡ Next Steps: Baada ya kumaliza hizi basics, endelea na: useContext, useReducer, Redux, Next.js (React framework), testing (Jest, React Testing Library), TypeScript + React.
← Back to All Courses