0: Vanilla JS Crash Course
Prerequisites for React — the DOM API is how JavaScript talks to HTML natively. React abstracts all of this, but understanding the raw browser APIs makes React’s model click and prepares you for general JavaScript interview questions.
1. Selecting Elements
Three ways to grab elements from the page:
// By ID — returns one element
const header = document.getElementById('header')
// By CSS selector — returns first match
const button = document.querySelector('.submit-btn')
// By CSS selector — returns ALL matches (NodeList)
const items = document.querySelectorAll('.list-item')Exercise: Fill in the blanks.
// Select the element with id="app"
const app = document._______('app')
// Select the first <p> tag inside a div with class "content"
const paragraph = document._______('.content p')
// Select ALL elements with class "card"
const cards = document._______('.card')2. Creating and Appending Elements
In React you write JSX. In vanilla JS, you manually create elements and attach them to the page.
const div = document.createElement('div') // create a <div>
div.textContent = 'Hello World' // set its text
div.style.color = 'red' // set inline style
div.className = 'greeting' // set CSS class
document.body.appendChild(div) // attach to pageExercise: Fill in the blanks.
// Create a <button> element
const btn = document._______('button')
// Set its text to "Click Me"
btn._______ = 'Click Me'
// Give it a class of "primary"
btn._______ = 'primary'
// Add it inside the element with id="toolbar"
document.getElementById('toolbar')._______(btn)3. Event Listeners
In React: onClick={handleClick}. In vanilla JS: addEventListener.
const button = document.querySelector('#my-btn')
button.addEventListener('click', () => {
console.log('clicked!')
})
// With the event object (same 'e' you know from React)
button.addEventListener('click', (e) => {
console.log(e.target) // the element that was clicked
})Exercise: Fill in the blanks.
const input = document.querySelector('#search')
// Listen for typing (same event as React's onChange)
input._______('input', (e) => {
console.log('User typed:', e._______.value)
})
// Listen for Enter key
input._______('keydown', (e) => {
if (e._______ === 'Enter') {
console.log('Submitted:', e.target.value)
}
})4. Modifying Existing Elements
Change what’s already on the page — text, styles, attributes, visibility.
const title = document.querySelector('h1')
title.textContent = 'New Title' // change text
title.style.backgroundColor = 'yellow' // change style
title.setAttribute('data-id', '42') // set attribute
title.classList.add('highlighted') // add a CSS class
title.classList.remove('hidden') // remove a CSS class
title.classList.toggle('active') // toggle a CSS classExercise: Fill in the blanks.
const card = document.querySelector('.card')
// Change the text inside the card
card._______ = 'Updated content'
// Add the CSS class "selected"
card.classList._______('selected')
// Set a custom data attribute
card._______('data-status', 'active')
// Change the background color
card._______.backgroundColor = 'lightblue'5. Removing Elements
const item = document.querySelector('.old-item')
item.remove() // that's it6. Building a List Dynamically
This is the vanilla JS version of .map() in React. Instead of returning JSX, you create elements in a loop and append them.
const fruits = ['Apple', 'Banana', 'Cherry']
const list = document.querySelector('#fruit-list') // an existing <ul>
fruits.forEach(fruit => {
const li = document.createElement('li')
li.textContent = fruit
list.appendChild(li)
})Exercise: Fill in the blanks to build a clickable list where clicking an item alerts its name.
const names = ['Alice', 'Bob', 'Charlie']
const container = document.querySelector('#names')
names.forEach(name => {
const div = document._______('div')
div._______ = name
div._______('click', () => {
alert('You clicked: ' + name)
})
container._______(div)
})7. Putting It Together — Mini Todo (no React)
This is the vanilla JS equivalent of your React TodoList. Same logic, different API.
Exercise: Fill in the blanks.
const input = document._______('#todo-input')
const addBtn = document._______('#add-btn')
const list = document._______('#todo-list')
addBtn._______('click', () => {
const text = input._______
if (!text) return
const li = document._______('li')
li._______ = text
// Add a delete button
const deleteBtn = document._______('button')
deleteBtn._______ = 'X'
deleteBtn._______('click', () => {
li._______()
})
li._______(deleteBtn)
list._______(li)
input.value = ''
})Key Differences from React
| React | Vanilla JS |
|---|---|
onClick={fn} | el.addEventListener('click', fn) |
{text} in JSX | el.textContent = text |
style={{color: 'red'}} | el.style.color = 'red' |
className="foo" | el.className = 'foo' |
.map() returns JSX | forEach + createElement + appendChild |
| State triggers re-render | You manually update the DOM |
| Component unmount cleans up | You manually call removeEventListener |