Week 4 - React Fundamentals

Why React?

Setting up a React project with Vite

Components

JSX

Props

Rendering lists

Conditional rendering

The mental model: how React renders (2)

Practice

Assignment

Front end Track

Week 4 Assignment: Rebuild Your Portfolio in React

Focus: Components, JSX, props, lists, conditional rendering

Description

Your portfolio already exists. You built the HTML structure in week 1 and styled it in week 2. This week you rebuild it in React — not from scratch, but as a deliberate translation: the same content, the same sections, the same visual result, now expressed as a component tree.

By the end of this assignment you'll have a React application running on localhost that looks identical to your week 2 portfolio, with every section broken into its own component, your projects rendered dynamically from an array, and the dark mode toggle wired back up in React.

What you're building on

Your week 2 portfolio should have:

You'll carry all of this forward. The CSS you wrote in week 2 moves over almost unchanged.

Requirements

1. Set up a new Vite + React project

npm create vite@latest portfolio-react -- --template react-ts
cd portfolio-react
npm install
npm run dev

Copy your styles.css from week 2 into src/styles.css and import it in main.tsx:

import './styles.css';

Delete the contents of src/App.tsx and src/App.css so you start from a clean slate.

2. Split your portfolio into components

Create the following structure inside src/:

Compose them in App.tsx:

import Header from './components/Header';
import About from './components/About';
import Projects from './components/Projects';
import Contact from './components/Contact';
import Footer from './components/Footer';

const projects = [
  // defined in step 3
];

export default function App() {
  return (
    <>
      <Header />
      <main>
        <About />
        <Projects projects={projects} />
        <Contact />
      </main>
      <Footer />
    </>
  );
}

Component requirements:

3. Add your projects as data

In week 1 and 2 your projects were hardcoded HTML. Now they live in a typed array in App.tsx:

interface Project {
  id: number;
  title: string;
  description: string;
  techStack: string[];
  url?: string;
}

const projects: Project[] = [
  {
    id: 1,
    title: 'Portfolio Page',
    description: 'The page you\\'re looking at — built with HTML and CSS in weeks 1 and 2.',
    techStack: ['HTML', 'CSS'],
    url: '',
  },
  // add at least 2 more — real or placeholder projects
];

Requirements:

4. Render the projects list with .map()

interface ProjectsProps {
  projects: Project[];
}

export default function Projects({ projects }: ProjectsProps) {
  if (projects.length === 0) {
    return <p>No projects yet.</p>;
  }

  return (
    <section>
      <h2>Projects</h2>
      <ul>
        {projects.map((project) => (
          <ProjectCard key={project.id} {...project} />
        ))}
      </ul>
    </section>
  );
}

Requirements:

5. Wire up the dark mode toggle

Your week 1 toggle used document.body.classList.toggle('dark-mode') with a plain event listener. In React, event handlers go directly on JSX elements:

export default function Header() {
  function handleThemeToggle() {
    document.body.classList.toggle('dark-mode');
  }

  return (
    <header>
      {/* your name, tagline, image */}
      <button onClick={handleThemeToggle}>Toggle dark mode</button>
    </header>
  );
}

Your week 2 .dark-mode CSS still applies — nothing changes there. The toggle just moves from script.js into the component.

<aside> 💡

This approach works fine for now. Next week you'll learn useState, which is the proper React way to track whether dark mode is on or off and keep the button label in sync.

</aside>

6. Add conditional rendering to ProjectCard

Requirements:

7. Verify and commit

npm run dev     # confirm everything renders without console errors or warnings
npm run build   # confirm the production build succeeds

The browser console must show no red errors and no yellow warnings — especially no missing key warnings.

Then push to your existing portfolio GitHub repository in a new branch called react:

  1. node_modules/ must be in .gitignore
  2. Update your README.md to mention the React rebuild and the run command
  3. Commit and push

Hints