React Interview Questions & Answers (2026) – RankWeb3
⚛️ React All Levels 30 Questions Updated 2026

React Interview
Questions & Answers

📅 Updated: March 2026
⏱️ Read time: ~22 min
🎯 30 questions — Beginner to Advanced
✍️ By RankWeb3 Team
30
Total Questions
10
Beginner
11
Intermediate
9
Advanced

🌱Beginner QuestionsQ1–Q10

1
What is React and why is it used?
BeginnerVery Common
+

React is an open-source JavaScript library (not a framework) for building user interfaces, created by Meta (Facebook) in 2013. It focuses on the View layer of an application.

  • Component-based: UIs are built from small, reusable, isolated pieces called components.
  • Declarative: You describe what the UI should look like, and React figures out how to update the DOM efficiently.
  • Virtual DOM: React maintains a lightweight copy of the DOM in memory, diffing and batching updates for performance.
  • Unidirectional data flow: Data flows down from parent to child via props, making state predictable and easy to debug.
  • Large ecosystem: React Router, Redux, React Query, Next.js — massive tooling support.
💡Library vs Framework: React only handles the UI. A framework like Angular includes routing, HTTP, forms, etc. out of the box. React lets you choose your own tools — that's its power and its complexity.
2
What is JSX and why does React use it?
BeginnerVery Common
+

JSX (JavaScript XML) is a syntax extension that lets you write HTML-like markup inside JavaScript. It's not HTML — it gets compiled by Babel into React.createElement() calls.

JSX
// JSX — what you write: const element = ( <div className="card"> <h1>Hello, {name}</h1> <p>Welcome to RankWeb3</p> </div> ); // What Babel compiles it to: const element = React.createElement( 'div', { className: 'card' }, React.createElement('h1', null, 'Hello, ', name), React.createElement('p', null, 'Welcome to RankWeb3') );

JSX rules to know: Use className not class. Use htmlFor not for. Every JSX expression must return a single root element (use <></> Fragment if needed). JavaScript expressions go inside {} curly braces.

3
What is the Virtual DOM and how does React use it?
BeginnerVery Common
+

The Virtual DOM is a lightweight JavaScript copy of the real DOM kept in memory. When state changes, React compares the new Virtual DOM against the previous version (a process called diffing), and only updates the parts of the real DOM that actually changed (reconciliation).

  • Step 1: State or props change → React creates a new Virtual DOM tree.
  • Step 2: React diffs the new tree against the previous one (using a reconciliation algorithm).
  • Step 3: Only the changed nodes are updated in the real DOM — not the whole page.
💡Why it matters: Direct DOM manipulation is slow. Batching and minimising real DOM changes (via the Virtual DOM) makes React fast, especially on pages with frequent state updates.
ℹ️React 18 introduced the Fiber architecture which improved reconciliation further with concurrent rendering, allowing React to pause and resume work, making UIs more responsive.
4
What are props in React?
BeginnerVery Common
+

Props (short for properties) are how you pass data from a parent component to a child component. They are read-only — a component must never modify its own props.

JSX
// Parent passes props down: function App() { return ( <UserCard name="Meraj" role="Developer" isActive={true} /> ); } // Child receives and uses props: function UserCard({ name, role, isActive }) { return ( <div> <h2>{name}</h2> <p>{role}</p> <span>{isActive ? "Online" : "Offline"}</span> </div> ); } // Default props: UserCard.defaultProps = { isActive: false };
5
What is state in React and how is it different from props?
BeginnerVery Common
+
FeatureStateProps
Owned byThe component itselfParent component
Mutable✅ Yes (via setter)❌ No (read-only)
Triggers re-render✅ Yes when changed✅ Yes when changed by parent
PurposeInternal component dataExternal configuration data
JSX
import { useState } from 'react'; function Counter({ initialCount = 0 }) { // prop const [count, setCount] = useState(initialCount); // state return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(c => c + 1)}>+</button> <button onClick={() => setCount(0)}>Reset</button> </div> ); }
6
What are React hooks? Name the most commonly used ones.
BeginnerVery Common
+

Hooks (introduced in React 16.8) are functions that let you use state and other React features in functional components — without writing a class. They always start with use.

JSX — Most Used Hooks
useState // manage local state useEffect // side effects (data fetching, subscriptions) useContext // consume context without Consumer wrapper useRef // mutable ref, DOM access, persist value without re-render useMemo // memoize expensive computed value useCallback // memoize function reference useReducer // complex state logic (like Redux, locally) useLayoutEffect // like useEffect but fires synchronously after DOM paint useId // generate unique IDs (React 18) useTransition // mark updates as non-urgent (React 18)
⚠️Rules of Hooks: (1) Only call hooks at the top level — never inside loops, conditions, or nested functions. (2) Only call hooks from React function components or custom hooks.
7
What is useEffect and when does it run?
BeginnerVery Common
+

useEffect lets you perform side effects in functional components — data fetching, subscriptions, manually updating the DOM, or setting up timers. It runs after the browser has painted the screen.

JSX
import { useState, useEffect } from 'react'; function UserProfile({ userId }) { const [user, setUser] = useState(null); // Dependency array controls WHEN effect runs: useEffect(() => { // no array → runs after EVERY render }); useEffect(() => { // empty [] → runs ONCE on mount only fetchUser(userId).then(setUser); }, []); useEffect(() => { // [userId] → runs on mount + when userId changes fetchUser(userId).then(setUser); // Cleanup function — runs before next effect or unmount: return () => { // cancel subscriptions, clear timers here }; }, [userId]); }
💡Why interviewers ask this: Forgetting cleanup functions causes memory leaks. Missing dependencies causes stale closures. Understanding the dependency array deeply is what separates mid-level from senior React devs.
8
What is the difference between a controlled and uncontrolled component?
BeginnerCommon
+
FeatureControlledUncontrolled
Data stored inReact stateDOM (via ref)
Source of truthReactDOM
Updated viaonChange + setStateref.current.value
ValidationEasy — on every keystrokeOn submit only
Best forMost form use casesFile inputs, simple forms
JSX
// Controlled — React owns the value: const [email, setEmail] = useState(''); <input value={email} onChange={e => setEmail(e.target.value)} /> // Uncontrolled — DOM owns the value: const emailRef = useRef(null); <input ref={emailRef} defaultValue="" /> // Access: emailRef.current.value
9
What are React keys and why are they important?
BeginnerVery Common
+

Keys are special string attributes that help React identify which items in a list have changed, been added, or removed. They allow React to efficiently reorder and update list items without re-rendering the entire list.

JSX
// ❌ Wrong — using index as key (causes bugs on reorder/delete): {items.map((item, index) => ( <li key={index}>{item.name}</li> ))} // ✅ Correct — use stable, unique ID: {items.map(item => ( <li key={item.id}>{item.name}</li> ))} // Keys must be unique among siblings, not globally: <ul> <li key="1">Item A</li> <li key="2">Item B</li> </ul>
⚠️Using array index as key is problematic when list items can be reordered, deleted, or inserted. It leads to incorrect component state, broken animations, and subtle rendering bugs.
10
What is the component lifecycle in React?
BeginnerVery Common
+

Every React component goes through three lifecycle phases. In modern React (functional components + hooks), useEffect handles all lifecycle events.

JSX
// ── Functional component lifecycle with useEffect ── function MyComponent() { useEffect(() => { // 🟢 MOUNTING — runs once after first render: console.log('Component mounted'); fetchData(); return () => { // 🔴 UNMOUNTING — cleanup runs before removal: console.log('Component unmounted'); }; }, []); // ← empty array = mount/unmount only useEffect(() => { // 🟡 UPDATING — runs when `count` changes: console.log('count updated:', count); }, [count]); } // Class component equivalent (for reference): // componentDidMount → useEffect(() => {}, []) // componentDidUpdate → useEffect(() => {}, [deps]) // componentWillUnmount→ useEffect(() => { return cleanup }, [])

Intermediate QuestionsQ11–Q21

11
What is the React Context API and when should you use it?
IntermediateVery Common
+

Context provides a way to pass data through the component tree without passing props down manually at every level (prop drilling). It's ideal for global data like themes, authentication, locale, or user preferences.

JSX
import { createContext, useContext, useState } from 'react'; // 1. Create context: const ThemeContext = createContext('light'); // 2. Provide it high in the tree: function App() { const [theme, setTheme] = useState('light'); return ( <ThemeContext.Provider value={{ theme, setTheme }}> <Navbar /> <MainContent /> </ThemeContext.Provider> ); } // 3. Consume anywhere in the tree: function Navbar() { const { theme, setTheme } = useContext(ThemeContext); return ( <nav className={theme}> <button onClick={() => setTheme(t => t === 'light' ? 'dark' : 'light')}> Toggle </button> </nav> ); }
💡Context vs Redux: Context is great for low-frequency updates (theme, auth). For high-frequency state changes (e.g., real-time data, complex async flows), use Redux Toolkit or Zustand — they're more optimised.
12
What is useReducer and when would you use it over useState?
IntermediateCommon
+

useReducer is an alternative to useState for managing complex state logic. It uses a reducer function — a pure function that takes the current state and an action, and returns the next state.

JSX
import { useReducer } from 'react'; const initialState = { count: 0, step: 1 }; function reducer(state, action) { switch (action.type) { case 'INCREMENT': return { ...state, count: state.count + state.step }; case 'DECREMENT': return { ...state, count: state.count - state.step }; case 'SET_STEP': return { ...state, step: action.payload }; case 'RESET': return initialState; default: return state; } } function Counter() { const [state, dispatch] = useReducer(reducer, initialState); return ( <div> <p>Count: {state.count} | Step: {state.step}</p> <button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button> </div> ); }

Use useReducer when: state has multiple related sub-values, the next state depends on complex logic, or when you want to co-locate state transitions in one place (easier to test).

13
What is the difference between useMemo and useCallback?
IntermediateVery Common
+
HookReturnsUse case
useMemoA memoized valueAvoid re-computing expensive calculations
useCallbackA memoized functionStable function ref for child props / deps
JSX
import { useMemo, useCallback, useState } from 'react'; function Dashboard({ items }) { const [filter, setFilter] = useState(''); // useMemo — recompute only when items/filter changes: const filteredItems = useMemo(() => items.filter(i => i.name.includes(filter)), [items, filter] ); // useCallback — stable function ref for child component: const handleDelete = useCallback((id) => { // delete logic }, []); // ← same function reference every render return ( <ItemList items={filteredItems} onDelete={handleDelete} // won't cause child re-render /> ); }
💡Don't over-memoize: Memoisation has a cost. Only use useMemo/useCallback when you have a measured performance problem. Premature memoisation adds complexity with no benefit.
14
What is useRef and what are its main use cases?
IntermediateCommon
+

useRef returns a mutable object with a .current property. It persists across renders but does not trigger a re-render when changed.

JSX
import { useRef, useEffect } from 'react'; function Form() { // 1. DOM access — focus input on mount: const inputRef = useRef(null); useEffect(() => { inputRef.current.focus(); }, []); // 2. Persist mutable value without re-render: const renderCount = useRef(0); renderCount.current += 1; // no re-render triggered // 3. Store previous value: const [count, setCount] = useState(0); const prevCount = useRef(count); useEffect(() => { prevCount.current = count; }, [count]); // 4. Store timer/interval ID for cleanup: const timerRef = useRef(null); const start = () => { timerRef.current = setInterval(tick, 1000); }; const stop = () => clearInterval(timerRef.current); return <input ref={inputRef} />; }
15
What is prop drilling and how do you avoid it?
IntermediateVery Common
+

Prop drilling happens when you pass props through multiple intermediate components that don't use the data themselves — just to get it to a deeply nested component.

JSX
// ❌ Prop drilling — user passed through every level: App(user) Layout(user) Sidebar(user) UserAvatar(user) // ✅ Solution 1: Context API const UserContext = createContext(); // Wrap App with Provider, consume in UserAvatar // ✅ Solution 2: Component composition (pass children) function Layout({ children }) { return <div>{children}</div>; // no user prop needed } // App renders: <Layout><UserAvatar user={user} /></Layout> // ✅ Solution 3: State management library // Redux Toolkit, Zustand, Jotai, Recoil
16
What is React.memo and how does it work?
IntermediateCommon
+

React.memo is a higher-order component that wraps a functional component and skips re-rendering if its props haven't changed (shallow comparison). It's the functional equivalent of PureComponent.

JSX
import { memo, useState, useCallback } from 'react'; // Memoised child — only re-renders when name/onClick changes: const ExpensiveChild = memo(function({ name, onClick }) { console.log('ExpensiveChild rendered'); return <button onClick={onClick}>{name}</button>; }); function Parent() { const [count, setCount] = useState(0); // Without useCallback, new function ref every render // → defeats React.memo (memo sees props changed) const handleClick = useCallback(() => { console.log('clicked'); }, []); return ( <> <p>Parent count: {count}</p> <button onClick={() => setCount(c => c+1)}>Increment</button> <ExpensiveChild name="Click me" onClick={handleClick} /> </> ); }
17
What are custom hooks and how do you create one?
IntermediateVery Common
+

Custom hooks are JavaScript functions that start with use and can call other hooks. They let you extract and reuse stateful logic across multiple components without changing the component hierarchy.

JSX
// Custom hook — reusable fetch logic: function useFetch(url) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const controller = new AbortController(); fetch(url, { signal: controller.signal }) .then(r => r.json()) .then(setData) .catch(e => { if (e.name !== 'AbortError') setError(e); }) .finally(() => setLoading(false)); return () => controller.abort(); }, [url]); return { data, loading, error }; } // Use in any component: function UserList() { const { data, loading, error } = useFetch('/api/users'); if (loading) return <Spinner />; if (error) return <Error msg={error.message} />; return data.map(u => <UserCard key={u.id} {...u} />); }
18
What is React Router and how does client-side routing work?
IntermediateVery Common
+

React Router is the standard routing library for React. Client-side routing updates the URL and renders different components without a full page reload, using the browser's History API.

JSX — React Router v6
import { BrowserRouter, Routes, Route, Link, useNavigate, useParams } from 'react-router-dom'; function App() { return ( <BrowserRouter> <nav> <Link to="/">Home</Link> <Link to="/blog">Blog</Link> </nav> <Routes> <Route path="/" element={<Home />} /> <Route path="/blog" element={<Blog />} /> <Route path="/blog/:id" element={<Post />} /> <Route path="*" element={<NotFound />} /> </Routes> </BrowserRouter> ); } // Access route params: function Post() { const { id } = useParams(); const navigate = useNavigate(); return <button onClick={() => navigate('/')}>Back</button>; }
19
What is the difference between class components and functional components?
IntermediateCommon
+
FeatureClass ComponentFunctional Component
Syntaxclass X extends Componentfunction X(props)
Statethis.state + setState()useState() hook
LifecycleLifecycle methodsuseEffect() hook
PerformanceSlightly more overheadLighter, modern default
RecommendedLegacy codebases✅ Modern React default
💡In 2026: Functional components with hooks are the standard. You may still encounter class components in legacy codebases, so understanding them is useful — but write new code as functional.
20
What is React.lazy and Suspense?
Intermediate
+

React.lazy enables code splitting — loading components only when they're needed, reducing the initial bundle size. Suspense shows a fallback UI while the lazy component loads.

JSX
import { lazy, Suspense } from 'react'; // Dynamically import — loaded only when rendered: const Dashboard = lazy(() => import('./Dashboard')); const Settings = lazy(() => import('./Settings')); function App() { return ( <Suspense fallback={<div>Loading...</div>}> <Routes> <Route path="/dashboard" element={<Dashboard />} /> <Route path="/settings" element={<Settings />} /> </Routes> </Suspense> ); }
21
What is the difference between useEffect and useLayoutEffect?
Intermediate
+
HookWhen it firesUse case
useEffectAfter browser has painted (asynchronous)Data fetching, subscriptions, timers
useLayoutEffectAfter DOM mutation, before browser paints (synchronous)DOM measurements, tooltip positioning
JSX
import { useLayoutEffect, useRef } from 'react'; function Tooltip({ text }) { const ref = useRef(null); useLayoutEffect(() => { // Measure DOM BEFORE browser paints — no flicker: const { width, height } = ref.current.getBoundingClientRect(); // position tooltip based on dimensions }, []); return <div ref={ref}>{text}</div>; }
💡Default to useEffect. Use useLayoutEffect only when you need to read or modify the DOM before the user sees it, to prevent visual flickering.

🔥Advanced QuestionsQ22–Q30

22
What is React Fiber architecture?
AdvancedCommon
+

React Fiber is the reconciliation engine introduced in React 16. It completely rewrote how React processes component updates to enable incremental rendering — the ability to split rendering work into chunks and spread it over multiple frames.

  • Problem with old reconciler (Stack): Rendering was synchronous and couldn't be interrupted. Large trees would block the main thread, causing janky UIs.
  • Fiber solution: Work is broken into units (fibers). React can pause work, return to it later, prioritise certain updates, and abort work that's no longer needed.
  • Priority levels: User interactions (clicks, typing) get higher priority than background data updates.
  • Concurrent Mode (React 18): Built on Fiber — enables concurrent rendering, startTransition, useTransition, and automatic batching.
💡In interviews: Don't need to know every internal detail. Know that Fiber enables incremental rendering, priority scheduling, and is what makes concurrent features like useTransition possible.
23
What are React's new concurrent features in React 18?
AdvancedCommon
+

React 18 shipped with several major concurrent features that improve responsiveness:

JSX — React 18 Features
import { useTransition, useDeferredValue, startTransition } from 'react'; // 1. Automatic Batching — multiple setState() batched in one render: setTimeout(() => { setCount(c => c+1); setFlag(f => !f); // React 18: one re-render (React 17: two re-renders) }, 1000); // 2. useTransition — mark updates as non-urgent: const [isPending, startTransition] = useTransition(); startTransition(() => { setSearchResults(heavyFilter(query)); // deferred }); // UI stays responsive, pending update runs in background // 3. useDeferredValue — defer re-rendering a value: const deferredQuery = useDeferredValue(query); // Use deferredQuery for expensive child renders // 4. createRoot (new render API): import { createRoot } from 'react-dom/client'; createRoot(document.getElementById('root')).render(<App />);
24
What are Higher-Order Components (HOCs)?
AdvancedCommon
+

A Higher-Order Component is a function that takes a component and returns a new enhanced component. It's a pattern for reusing component logic. Common in older React code — largely replaced by custom hooks in modern React.

JSX
// HOC that adds authentication guard: function withAuth(WrappedComponent) { return function AuthenticatedComponent(props) { const isAuthenticated = useAuth(); if (!isAuthenticated) { return <Navigate to="/login" />; } return <WrappedComponent {...props} />; }; } // Usage: const ProtectedDashboard = withAuth(Dashboard); // HOC that adds loading state: function withLoading(Component) { return function({ isLoading, ...props }) { return isLoading ? <Spinner /> : <Component {...props} />; }; }
💡HOCs vs Custom Hooks: Custom hooks are now preferred for logic reuse — they're simpler, don't create wrapper hell, and work with hooks. HOCs are still used for component wrapping (like React.memo, connect in Redux).
25
What is React's reconciliation algorithm?
Advanced
+

Reconciliation is the process React uses to update the DOM efficiently by comparing the new Virtual DOM tree with the previous one (diffing). React applies two heuristics to make this O(n) instead of the naive O(n³) solution:

  • Heuristic 1 — Element type: If two elements have different types (e.g., <div> vs <span>), React destroys the old subtree and builds a new one from scratch.
  • Heuristic 2 — Keys: When rendering lists, React uses key props to match elements across renders. Same key = same element, reuse it. Different/missing key = destroy and rebuild.
JSX
// Same type — React UPDATES (efficient): // Before: <Button className="old" /> // After: <Button className="new" /> // → React just updates the className attribute // Different type — React DESTROYS and REBUILDS: // Before: <div><Counter /></div> // After: <span><Counter /></span> // → Counter's state is LOST (new tree from scratch) // Keys in lists — React REORDERS without destroying: // Before: [A(key=1), B(key=2), C(key=3)] // After: [C(key=3), A(key=1), B(key=2)] // → State of A, B, C all PRESERVED (just moved)
26
What are React Error Boundaries?
Advanced
+

Error Boundaries are class components that catch JavaScript errors anywhere in their child component tree, log them, and display a fallback UI instead of crashing the whole application.

JSX
class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false, error: null }; } static getDerivedStateFromError(error) { return { hasError: true, error }; // update state to show fallback } componentDidCatch(error, info) { // log to error reporting service (Sentry, etc.) logError(error, info.componentStack); } render() { if (this.state.hasError) { return <h2>Something went wrong. <button onClick={() => this.setState({ hasError: false })}>Retry</button></h2>; } return this.props.children; } } // Usage — wrap risky sections: <ErrorBoundary> <PaymentWidget /> </ErrorBoundary>
ℹ️Error boundaries must currently be class components. They do NOT catch errors in event handlers, async code, or SSR. Use regular try/catch for those cases.
27
How do you optimise React application performance?
AdvancedVery Common
+

React performance optimisation covers multiple layers:

JSX — Performance Checklist
// 1. Prevent unnecessary re-renders: const Child = memo(({ data }) => <div>{data}</div>); const handler = useCallback(() => {}, []); // 2. Memoize expensive computations: const sorted = useMemo(() => items.sort(compareFn), [items]); // 3. Code split with lazy loading: const HeavyChart = lazy(() => import('./HeavyChart')); // 4. Virtualise long lists: // react-window or react-virtual // Only render visible rows, not all 10,000 // 5. Debounce expensive handlers: const debouncedSearch = useMemo( () => debounce(handleSearch, 300), [] ); // 6. Use React 18 concurrent features: const [isPending, startTransition] = useTransition(); startTransition(() => setHeavyState(newVal)); // 7. Profile first — use React DevTools Profiler // Don't optimise blindly!
28
What is Server-Side Rendering (SSR) in React and how does Next.js enable it?
AdvancedCommon
+
  • CSR (Client-Side Rendering): Browser downloads empty HTML + JS bundle, React renders everything in the browser. Slow initial load, bad SEO.
  • SSR (Server-Side Rendering): Server renders HTML on each request, sends fully-formed HTML to browser. Fast first paint, good SEO. React then "hydrates" it (attaches event handlers).
  • SSG (Static Site Generation): HTML pre-rendered at build time. Ultra-fast, perfect for content that rarely changes.
JSX — Next.js Data Fetching
// getServerSideProps — SSR on every request: export async function getServerSideProps(context) { const data = await fetchUser(context.params.id); return { props: { data } }; } // getStaticProps — SSG at build time: export async function getStaticProps() { const posts = await fetchAllPosts(); return { props: { posts }, revalidate: 60 }; // ISR every 60s } // Next.js 13+ App Router — React Server Components: async function Page({ params }) { // server component by default const data = await db.query(...); // direct DB access! return <div>{data}</div>; }
29
What are React Server Components and how are they different from Client Components?
AdvancedCommon
+
FeatureServer ComponentClient Component
Runs onServer onlyBrowser (+ server for hydration)
Bundle sizeZero JS sent to clientIncluded in JS bundle
Can use hooks?❌ No✅ Yes
Can use state/effects?❌ No✅ Yes
Direct DB/FS access?✅ Yes❌ No
DirectiveDefault in Next.js App Router'use client' at top
JSX — Next.js App Router
// Server Component (default) — no 'use client' async function BlogPost({ id }) { const post = await db.posts.find(id); // direct DB access return <article>{post.content}</article>; } // Client Component — interactive parts 'use client'; function LikeButton({ postId }) { const [liked, setLiked] = useState(false); return <button onClick={() => setLiked(l => !l)}></button>; }
30
What are common React anti-patterns to avoid?
AdvancedVery Common
+
JSX — Anti-patterns to Avoid
// ❌ 1. Mutating state directly: state.items.push(newItem); // won't trigger re-render // ✅ Return new array: setItems(prev => [...prev, newItem]); // ❌ 2. useEffect with missing dependencies: useEffect(() => { doSomething(value); }, []); // stale closure // ✅ Include all dependencies: useEffect(() => { doSomething(value); }, [value]); // ❌ 3. Inline object/array in JSX (new reference every render): <Child style={{ color: 'red' }} /> // defeats React.memo // ✅ Define outside or useMemo: const style = useMemo(() => ({ color: 'red' }), []); // ❌ 4. Array index as key in dynamic lists: items.map((item, i) => <Row key={i} />) // ✅ Use stable unique ID: items.map(item => <Row key={item.id} />) // ❌ 5. Storing derived state in useState: const [fullName, setFullName] = useState(`${first} ${last}`); // ✅ Compute it (derived values don't need state): const fullName = `${first} ${last}`;

Up Next: HTML & CSS Interview Questions

You've covered React. The next page in the series covers HTML semantics, CSS Flexbox, Grid, animations, specificity, and responsive design. Coming soon.

← Python Q&A