A Humanities Student's Journey to Understanding Frontend Paradigm Shifts
Why I Decided to Take a Frontend Course
I am a graduate student from the humanities research field of Human-AI Interaction (HCI). Since I am not a major in this area, I learned development not through school classes but via YouTube lectures, blogs, and conversations with AI. After starting graduate school, I have been learning what I need as I conduct research. Through self-study, I could make something, but I couldn't tell if my code was well-written or followed standard practices, and working with AI only intensified this doubt.
Therefore, I decided to take a recommended frontend course for undergraduates. Starting from HTML/CSS, through JavaScript, and then React, writing code myself helped me understand the overall structure of frontend development. I wanted to internalize how the paradigm has shifted over time.
Course Process
The most impressive experience in the assignments was developing the same service in different ways. For instance, writing a To-do app using different syntaxes and separating frontend and backend by connecting a database.
How the Screen is Rendered
In the first week, I built the Todo app using only JavaScript. Data was stored in a single array, and the UI was drawn directly through DOM manipulation.
function renderTodos() {
todoList.innerHTML = '';
todos.forEach(todo => {
const li = createTodoElement(todo);
todoList.appendChild(li);
});
}
When adding a task, it was appended to the array, and then renderTodos() was called to redraw the entire screen. At this point, whenever data changed, the developer had to manually command "now redraw the screen." This method is intuitive. But one question arose: what if there are 100 elements on the screen? For every event, you have to manually track which elements to redraw. As the app grows larger, the amount the developer needs to handle increases exponentially. Adding a task meant putting it into the array and then calling renderTodos() to redraw the entire screen. This approach requires the developer to explicitly command the screen to redraw every time the data changes. Although intuitive, its limitations become apparent as app size grows. For each event, you must track which elements to update, and the developer’s responsibilities increase exponentially.
Data Storage
In the second Todo app, I connected an Express server with MongoDB. Now, data is stored not in browser memory but in the database. It doesn’t disappear even after refreshing. The client no longer holds data directly but requests it from the server when needed.
export async function fetchTodos() {
const res = await fetch(`${BASE_URL}/todos`);
return res.json();
}
export async function createTodo(title) {
const res = await fetch(`${BASE_URL}/todos`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title, completed: false }),
});
return res.json();
}
Component Concept
Moving to React, I did clone coding of Airbnb. Through this, I learned the component concept, which views the UI as independent units. Airbnb consisted of distinct sections like headers, search bars, and card lists; React breaks each of these into independent components.
<BrowserRouter>
<Header onSearch={handleSearch} />
<Routes>
<Route path="/" element={<MainPage results={results} hasSearched={hasSearched} />} />
</Routes>
</BrowserRouter>
These can be used like HTML tags, and necessary data is passed via props. Each component reacts only to the data passed to it, so it becomes much easier to track which parts of the screen update when certain data changes.
The state management style also changed. If search results are declared with useState, calling setResults(data) automatically re-renders the related components.
const [results, setResults] = useState([]);
const handleSearch = async ({ city, guests }) => {
const data = await fetch(`/api/accommodates?${params}`).then(r => r.json());
setResults(data);
};
Between AI and Basics
What I remember most from building my basics through the course assignments was encountering inconvenient syntax firsthand. Until then, I had just used whatever AI-recommended best framework, but I came to understand that React’s state management exists to solve the hassle of manually manipulating the DOM.
AI is a terrific tool. It quickly solves blocks and suggests directions I might not have thought of. But to understand code generated by AI, fundamental concepts are ultimately necessary. Through this course, when I write code in the future, I want to cultivate the habit of first explaining to myself 'why this problem should be solved this way' before asking AI for code. I want to consciously learn development knowledge with the mindset that AI is a tool to expand what I understand, not to replace my understanding.