48 React Interview Questions for Beginners
Prepare for your next React interview with this list of 48 questions, perfect for beginners and updated to 2024. Whether you're brushing up on the basics or learning React for the first time, these questions will help you ace your technical interviews with confidence.
Get the latest frontend development resources delivered straight to your inbox for free.
Explore our latest issue for a sample.
π The Complete Web Developer in 2024
- Efficiently updates and renders components when data changes.
- Helps manage UI complexity in large applications.
- Platform-agnostic (works for web, mobile, 3D apps).
- Different parts of Facebookβs UI got out of sync because they were powered by separate views.
- React ensures that when the state changes, the UI updates automatically, fixing the issue.
- Function components (preferred): Simple JavaScript functions.
- Class components: Legacy, based on ES6 classes.
- React uses a virtual DOM to manage updates efficiently.
- It interacts with the actual DOM to create, update, and delete elements based on the application state.
- Reduces the number of costly DOM manipulations.
- Improves performance by applying only necessary changes to the real DOM.
- The HTML element type (
'p'
for paragraph). - Properties (an object containing attributes, like
{ id: 'hello' }
). - The content/children of the element (
'Hello World!'
). - The
React.createElement
function returns a JavaScript object that describes the element. - This object contains information like the type of the element, its props (properties), and its children.
- React uses this object to eventually render the actual DOM element.
- Select the root element in the DOM.
- Create the root with
ReactDOM.createRoot
. - Render the React element using
root.render()
. - React: Handles the logic and structure of components (e.g.,
React.createElement
, state, props). - ReactDOM: Bridges React and the browser DOM (e.g.,
ReactDOM.render
orReactDOM.createRoot
). - React 18's createRoot() can handle updates in the background, making apps faster than React 17βs ReactDOM.render(), which did everything at once.
- In React 18, updates (even for things like timeouts) are grouped together, so the app refreshes less often. React 17 only did this for clicks or other direct user actions.
- React 18's Suspense feature now helps load data more smoothly, making the app feel faster.
- createRoot() gives developers more control over how the app updates and allows smoother, faster changes.
- Handles multiple JS files and dependencies.
- Improves loading time and application performance.
- Allows code to use advanced JS features like JSX.
- Include React and ReactDOM scripts using a CDN.
- Use
React.createElement
to define components. - Use
ReactDOM.createRoot
to render the component. react-dom
for web applications.react-native
for mobile apps (iOS/Android).react-three-fiber
for 3D applications using WebGL.- Automatically handles React imports
- Uses an optimized _jsx function
- Removes the need to import React manually
- Produces more efficient code
- Tag Closing: All elements must be explicitly closed, unlike HTML where certain tags, such as
<br>
or<img>
, can be left unclosed. - Attributes: JSX attributes use camelCase naming conventions because JSX integrates closely with JavaScript, which is case-sensitive. This ensures consistency between JSX and JavaScript properties.
- Reserved Words: Certain words, like class and for, are reserved in JavaScript because they have predefined meanings. To avoid conflicts, these words must be replaced in JSX with className and htmlFor, respectively.
- Lowercase tags for standard HTML elements (
div
,p
,span
). - Uppercase tags for custom React components (e.g.,
MyComponent
). - The JSX compiler uses tag names to decide whether to render a native DOM element or invoke a custom component.
- Writing tags in the wrong case can lead to errors or unexpected behavior.
- The double curly braces represent: outer pair for JSX expression, inner pair for object literal
- Property names are in camelCase instead of kebab-case
- Values must be strings or numbers
- Numbers automatically get 'px' appended for relevant properties
- Vendor prefixes start with a capital letter (e.g., WebkitTransition)
- JSX automatically translates these attributes into valid HTML without modification.
- They are particularly useful when enhancing user experience or ensuring compliance with accessibility standards.
useState
for state managementuseEffect
for managing side effects (like API calls)useRef
for accessing DOM elements directlystate
holds the current state value.setState
updates the state value.initialValue
is the starting value for the state.- Always call
useState
at the top level of a functional component. - Hooks cannot be used conditionally.
- Changing state triggers a re-render of the component.
- Its state or props change.
- A parent component re-renders it.
- Form elements (like
<input>
or<select>
) derive their values from React state. - Updates happen via an onChange event handler.
- Never use hooks inside loops, conditionals, or nested functions.
- Always call hooks at the top level of your component.
- Screen readers work better with native form elements.
- Using
<div>
for input logic is discouraged unless absolutely necessary. - Fetching data from an API.
- Updating the browser DOM manually.
- Setting up timers, subscriptions, or event listeners.
- Runs after the render and can optionally clean up after itself.
- Accepts a dependency array as the second argument to control when it runs:
- No array: Runs after every render.
- Empty array ([]): Runs only once after the first render.
- Dependencies: Runs whenever specified dependencies change.
- Return a function from the useEffect callback for cleanup.
- Useful for canceling requests or clearing intervals.
useEffect
without a dependency array runs on every render.- State updates inside
useEffect
can cause re-renders, creating a loop if dependencies aren't properly managed. - Add dependencies to the array to prevent unnecessary calls.
- Initialize
loading
totrue
before the fetch starts. - Set loading to false after the data is fetched.
- Use conditional rendering (e.g., ternary operators) to display "Loading..." until data is available.
- Include all state or props accessed in the effect in the dependency array.
- Avoid leaving the array empty unless the effect should only run once.
- Avoid direct updates to dependencies within the effect to prevent loops.
- Keeps the DOM stable during re-renders.
- Helps React differentiate between elements, especially in lists.
- Prevents potential rendering bugs when elements are swapped or reordered.
- Assign a unique value (like id) as the key.
- Avoid using indices as keys unless absolutely necessary.
- Does not uniquely identify items when their order changes.
- React may mistakenly associate incorrect elements with their previous position.
- Static lists: The list does not change (no additions, deletions, or reordering).
- Non-critical elements: Rendering inaccuracies won't impact the app's functionality or user experience.
- Performance considerations: Simpler cases where the overhead of assigning unique keys is unnecessary.
What is React, and why was it developed?
React is a JavaScript library for building dynamic user interfaces. It was developed by Facebook to solve issues with UI consistency and state synchronization across different parts of the app.
Key features of React:
What problem did React solve for Facebook?
React helped solve the issue of "phantom messages" by keeping the UI and state synchronized, eliminating bugs caused by inconsistencies between different parts of the UI.
Why was this important?
What is a React component?
A React component is a reusable piece of UI. It is either a function or a class that accepts inputs (props) and returns React elements to describe what should appear on the screen.
Types of components:
Example (Function Component):
const Greeting = () => {
return React.createElement('h1', null, 'Hello, React Component!');
};
Example (Class Component):
class Greeting extends React.Component {
render() {
return React.createElement('h1', null, 'Hello from Class Component!');
}
}
What is the DOM, and how does React interact with it?
The DOM (Document Object Model) is a tree-like structure that represents a web page's HTML elements. It allows programming languages like JavaScript to dynamically interact with the content, structure, and style of a website.
Example of a DOM Structure:
For this HTML:
<!DOCTYPE html>
<html>
<body>
<div id="root">
<h1>Hello World</h1>
<p>This is a paragraph.</p>
</div>
</body>
</html>
The DOM tree structure would look like this:
html
βββ body
βββ div#root
βββ h1 (Hello World)
βββ p (This is a paragraph.)
Key points:
How does Reactβs virtual DOM differ from the regular DOM?
The virtual DOM is a lightweight copy of the real DOM. React uses it to determine the minimal changes necessary to update the actual DOM.
Advantages:
How do you create a basic React element?
You can create a React element using the React.createElement
function.
const element = React.createElement('p', { id: 'hello' }, 'Hello World!')
Arguments:
How React.createElement
works:
{
type: 'p',
key: null,
ref: null,
props: {
id: 'hello',
children: 'Hello World!',
},
_owner: null,
_store: {}
}
What are props in React, and how do you use them?
Props (short for properties) are objects passed from a parent component to a child component to configure or display dynamic content.
const Pizza = (props) => {
return (
<div>
<h1>{props.name}</h1>
<p>{props.description}</p>
</div>
);
};
const App = () => {
return <Pizza name="Hawaiian Pizza" description="Pineapple and ham" />;
};
How do you render a React element to the DOM?
React elements are rendered to the DOM using the render
method.
import { createRoot } from 'react-dom/client'
const container = document.querySelector('#root')
const root = createRoot(container)
root.render(element)
Steps:
How do React and ReactDOM differ?
React is the core library for building user interfaces, while ReactDOM is the library for rendering React components into the DOM.
// Import the libraries
import React from 'react';
import ReactDOM from 'react-dom/client';
// Create a React component
const App = () => React.createElement('h1', null, 'Hello from React!');
// Render the component into the DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(App());
What are the differences between React 17 and React 18 rendering methods?
In React 17, the ReactDOM.render
method was used to render components, while in React 18, this was changed to createRoot
and render
.
Old approach:
ReactDOM.render(element, container)
New approach (React 18):
const root = createRoot(container)
root.render(element)
Key Reasons for React 17 to React 18 Update:
How does the build system help React applications?
React uses a build system to bundle all JavaScript files and dependencies together into one output, optimizing performance and making modern JavaScript features available.
Benefits:
How can you serve a React application without a build step?
You can serve a React application without a build step by using a CDN to load React and ReactDOM, creating a basic HTML file, and writing JavaScript directly.
Steps:
<!DOCTYPE html>
<html lang="en">
<head>
<title>React Without Build</title>
</head>
<body>
<div id="root"></div>
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<script>
const root = ReactDOM.createRoot(document.getElementById('root'));
const App = () => React.createElement('h1', null, 'Hello React Without Build!');
root.render(React.createElement(App));
</script>
</body>
</html>
What platforms can React be used for?
React is platform-agnostic, meaning it can be used to build UIs for web, mobile, and even 3D environments.
Common platforms React supports:
What is the role of createRoot in React 18?
In React 18, createRoot is a key API for managing how a React application is rendered and how its lifecycle is handled. It is part of the transition to a more efficient rendering system that introduces concurrent rendering, improving the responsiveness of React applications.
const container = document.querySelector('#root')
const root = createRoot(container)
root.render(<App />)
What is JSX, and why do we need a build system for it?
JSX is a syntax extension for JavaScript that lets you write HTML-like code directly in your JavaScript files. It was popularized by React and makes it much more intuitive to describe UI components.
const element = (
<div className="greeting">
<h1>Hello, {name}</h1>
<p>Welcome to our site!</p>
</div>
);
We need a build system for JSX because:
Browsers don't understand JSX, browsers can only read standard JavaScript. The JSX code above isn't valid JavaScript, so it needs to be transformed into something like:
const element = React.createElement(
"div",
{ className: "greeting" },
React.createElement("h1", null, "Hello, ", name),
React.createElement("p", null, "Welcome to our site!")
);
What is the difference between `.js` and `.jsx` file extensions in React?
Initially, .jsx
was required to differentiate JSX code from plain JavaScript. Now, tools can handle JSX in .js
files, but some build tools like Vite may require .jsx
. It's mainly a convention and depends on project settings.
What's the difference between JSX and traditional React.createElement?
JSX is a simpler way to write React elements. While both create the same result, JSX is much more readable and maintainable.
// JSX way - easier to read
const element = (
<div className="container">
<p>Hello!</p>
</div>
);
// Traditional way - harder to read
const element = React.createElement(
'div',
{ className: 'container' },
React.createElement('p', null, 'Hello!')
);
Why do we use parentheses with JSX
Parentheses in JSX are used for formatting purposes. They allow us to write multi-line JSX code clearly and ensure proper parsing.
const element = (
<div>
<h1>Title</h1>
<p>Content</p>
</div>
);
Do we need to import React to use JSX?
In earlier React versions, importing React was required when using JSX, as JSX compiled into React.createElement
calls. However, starting in React 17, the JSX transformer automatically handles this, so explicit imports arenβt necessary for JSX alone.
The modern JSX transform (React 17+):
// Modern transform result
import { jsx as _jsx } from 'react/jsx-runtime';
const element = _jsx('h1', { children: 'Hello' });
What are Expression Slots in JSX?
Expression slots are created using curly brackets {}
in JSX and allow you to embed JavaScript expressions within JSX code. Anything inside {}
is treated as pure JavaScript instead of a string.
const name = "John";
const element = <div>Hello, {name}!</div>;
How do you add comments in JSX?
Comments in JSX must be placed inside expression slots using the {/* */}
syntax. Single-line comments (//
) don't work because they would break the expression slot closure.
const element = (
<div>
{/* This is a valid JSX comment */}
<p>Some content</p>
</div>
);
How do expression slots work with attributes in JSX?
Attribute expression slots allow you to dynamically set attribute values using JavaScript expressions within curly braces {}.
const uniqueId = 'content-wrapper';
const element = <div id={uniqueId}>Hello World</div>;
Here, the id attribute value is dynamically set to uniqueId.
Equivalent compiled code:
const element = React.createElement(
'div',
{ id: uniqueId },
'Hello World'
);
Can you use expressions other than simple variables in JSX expression slots?
Yes, any valid JavaScript expression can be used within an expression slot, including functions, arithmetic, and string operations.
const userEmail = '[email protected]';
const element = <div id={userEmail.replace('@', '-')}>User Info</div>;
This replaces @ with -, resulting in example-domain.com at runtime.
How does JSX handle type coercion in expression slots for attributes?
JSX automatically converts types as needed in expression slots, especially for boolean and numeric attributes. For example, both a string "true" and a boolean true
can be used interchangeably, as JSX converts these values to meet HTML attribute requirements.
// Both are valid
<input required="true" />
<input required={true} />
// Numeric attributes
<input type="range" min="1" max="5" />
<input type="range" min={1} max={5} />
What's the difference between compile-time and run-time in JSX expressions?
At compile-time, JSX is converted to React.createElement()
calls, but the expressions aren't evaluated. The actual evaluation of expressions happens at run-time when the code executes in the browser. This is why expression slots must contain expressions, not statements.
// This code...
const element = (
<div>
Count: {count + 1}
</div>
);
// ...compiles to:
const element = React.createElement(
'div',
null,
'Count: ',
count + 1
);
What are the limitations and best practices for boolean attributes in JSX?
Boolean attributes in JSX can be written in multiple ways, but the most explicit and recommended approach is to clearly state the value using an expression slot. This practice makes the code more maintainable and future-proof.
Best Practice Example:
// Most explicit and recommended
<input required={true} />
// Less recommended but valid
<input required="true" />
<input required />
What are the differences between HTML and JSX syntax?
JSX is a syntax extension for JavaScript that looks similar to HTML but has some distinct differences. It follows unique rules to integrate seamlessly with React's rendering system:
Why does JSX require self-closing tags for void elements?
In HTML, certain elements, known as "void elements," donβt require a closing tag because they are self-contained and cannot have child elements. Examples of void elements include <img>
, <input>
, <br>
, <meta>
, and <hr>
. Browsers automatically handle these unclosed tags correctly in plain HTML.
While HTML allows flexibility with void elements, JSX requires strict syntax rules to ensure consistency, clarity, and compatibility with JavaScript. This enforcement simplifies debugging, prevents ambiguity, and aligns JSX closely with the logic of the underlying React framework.
Why is case sensitivity important in JSX?
JSX distinguishes between:
This distinction is important because:
// Lowercase for native HTML elements
const element = (
<main>
<header>
<h1>Hello World!</h1>
</header>
<p>Welcome to React.</p>
</main>
);
// Uppercase for custom React components
function WelcomeMessage() {
return <h2>Welcome!</h2>;
}
const app = <WelcomeMessage />;
How do inline styles work in JSX?
Inline styles in JSX differ from traditional HTML styles. Instead of using a string, JSX requires you to pass a JavaScript object to the style attribute.
Important considerations:
// HTML version
<div style="font-size: 16px; background-color: blue; margin-top: 10px;">
// JSX version
<div style={{
fontSize: '16px',
backgroundColor: 'blue',
marginTop: '10px'
}}>
How do data and ARIA attributes differ in JSX?
In JSX, data- and ARIA (aria-) attributes retain their original dashed-case names, unlike standard HTML attributes that often convert to camelCase (e.g., className
instead of class
).
const element = (
<button data-test-id="test-button" aria-label="Close dialog" aria-hidden="false">
Click me
</button>
);
What are React Hooks?
React Hooks are special functions that let you use React features (like state and lifecycle methods) in functional components. They make components interactive and manage side effects or state.
Examples of React Hooks:
import React, { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
What is the useState Hook used for?
The useState
Hook is used to add state to functional components. It lets you declare a state variable and update it when needed.
const [state, setState] = useState(initialValue);
Key Points:
function Example() {
const [name, setName] = useState("John");
return (
<div>
<p>Name: {name}</p>
<button onClick={() => setName("Jane")}>Change Name</button>
</div>
);
}
How does React decide when to re-render a component?
React re-renders a component when:
React uses a Virtual DOM to compare the old and new states of the UI and only updates the changed parts, minimizing real DOM operations.
What is a controlled component in React?
A controlled component is a form element (like an input or select) whose value is controlled by React state. Instead of relying on the browser's default behavior, React fully manages its value through state and updates it when a user interacts with it.
Key Points:
import React, { useState } from "react";
function PizzaOrderForm() {
const [pizzaType, setPizzaType] = useState("Pepperoni");
return (
<div>
<label>
Pizza Type:
<select value={pizzaType} onChange={(e) => setPizzaType(e.target.value)}>
<option value="Pepperoni">Pepperoni</option>
<option value="Hawaiian">Hawaiian</option>
<option value="Veggie">Veggie</option>
</select>
</label>
<p>You selected: {pizzaType}</p>
</div>
);
}
Why does React enforce that hooks are always called in the same order?
React relies on the strict order of hooks in a component to manage internal state. If hooks are called conditionally or out of order, React will mix up the state values, leading to bugs.
Key Points:
Code Example (Incorrect Usage):
if (someCondition) {
const [state, setState] = useState(false); // β Incorrect
}
Code Example (Correct Usage):
const [state, setState] = useState(false); // β
Always at the top level
if (someCondition) {
// Perform conditional logic here
}
What is the purpose of the onChange handler in forms?
The onChange
handler listens for user interactions with form elements. When a user updates a field, the event is captured, and the handler updates the corresponding React state.
function PizzaSizeSelector() {
const [pizzaSize, setPizzaSize] = useState("Medium");
return (
<div>
<label>
Pizza Size:
<select value={pizzaSize} onChange={(e) => setPizzaSize(e.target.value)}>
<option value="Small">Small</option>
<option value="Medium">Medium</option>
<option value="Large">Large</option>
</select>
</label>
<p>Selected size: {pizzaSize}</p>
</div>
);
}
Why shouldn't you use change handlers on non-form elements like div tags?
Adding change handlers on non-form elements like <div>
can lead to accessibility issues. Instead, use form elements (<input>
, <select>
, etc.), which are accessible to assistive technologies.
Key Points:
// Correct
<label>
Select a pizza size:
<select value={size} onChange={(e) => setSize(e.target.value)}>
<option value="Small">Small</option>
<option value="Medium">Medium</option>
<option value="Large">Large</option>
</select>
</label>
// Avoid this pattern
<div onChange={(e) => setSize(e.target.value)}>Select size here</div>
What is useEffect in React?
useEffect
is a React Hook that allows you to handle side effects in functional components. Side effects are operations that interact with the outside world or affect something outside the component's scope, such as:
Key Points:
import React, { useState, useEffect } from 'react';
function DataFetcher() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data));
}, []); // Empty array means it runs only once
return <div>Data: {data ? JSON.stringify(data) : 'Loading...'}</div>;
}
Why canβt useEffect callbacks be async and how do you handle asynchronous code in useEffect?
The useEffect
callback cannot be async
because React expects the callback to return either nothing or a cleanup function, not a Promise
. To handle asynchronous code, define the async function inside the effect or outside it and then call it.
import React, { useState, useEffect } from 'react';
function AsyncExample() {
const [data, setData] = useState(null);
useEffect(() => {
async function fetchData() {
const res = await fetch('/api/data');
const json = await res.json();
setData(json);
}
fetchData(); // Call the async function
}, []); // Dependency array ensures it runs once
return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>;
}
What are cleanup functions in useEffect, and when are they used?
Cleanup functions in useEffect are used to clean up resources like subscriptions, timers, or API calls when the component unmounts or before the effect re-runs.
Key Points:
import React, { useState, useEffect } from 'react';
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => setSeconds(s => s + 1), 1000);
return () => clearInterval(interval); // Cleanup on unmount
}, []); // Empty array ensures it sets up the interval only once
return <p>Seconds elapsed: {seconds}</p>;
}
Why does React's useEffect sometimes cause endless re-renders?
If useEffect
is missing its dependency array or the dependencies aren't correctly specified, it may trigger a re-render loop. This happens because updating state in the effect causes another render, which calls the effect again, and so on.
Key Points:
import { useState, useEffect } from "react";
function PizzaComponent() {
const [pizzaSize, setPizzaSize] = useState("medium");
const [price, setPrice] = useState(null);
useEffect(() => {
// This runs whenever pizzaSize changes
console.log(`Fetching price for ${pizzaSize} pizza`);
setPrice(fetchPriceForSize(pizzaSize)); // Assume fetchPriceForSize is defined
}, [pizzaSize]); // Dependency array prevents unnecessary calls
return (
<div>
<button onClick={() => setPizzaSize("small")}>Small</button>
<button onClick={() => setPizzaSize("medium")}>Medium</button>
<button onClick={() => setPizzaSize("large")}>Large</button>
<p>Price: {price}</p>
</div>
);
}
How can you handle loading states when fetching data in React?
Use a loading
state variable to indicate whether data is being fetched. Conditionally render content based on this variable.
Key Points:
import { useState, useEffect } from "react";
function PizzaLoader() {
const [loading, setLoading] = useState(true);
const [pizza, setPizza] = useState(null);
useEffect(() => {
setTimeout(() => {
// Simulate fetching data
setPizza({ name: "Pepperoni", size: "medium", price: 15 });
setLoading(false);
}, 2000);
}, []);
return (
<div>
{loading ? (
<p>Loading pizza...</p>
) : (
<p>
Pizza: {pizza.name} - {pizza.size} (${pizza.price})
</p>
)}
</div>
);
}
How can you avoid over-fetching in useEffect?
Ensure that your useEffect
dependency array is accurate and only includes variables that need to trigger the effect. This prevents unnecessary API calls.
Key Points:
import { useState, useEffect } from "react";
function PizzaSizeTracker() {
const [size, setSize] = useState("medium");
const [price, setPrice] = useState(null);
useEffect(() => {
// Only fetch when size changes
fetch(`/api/pizza-price?size=${size}`)
.then((res) => res.json())
.then((data) => setPrice(data.price));
}, [size]);
return (
<div>
<select value={size} onChange={(e) => setSize(e.target.value)}>
<option value="small">Small</option>
<option value="medium">Medium</option>
<option value="large">Large</option>
</select>
<p>Price: {price}</p>
</div>
);
}
What is the purpose of the key prop in React?
The key
prop helps React identify which elements have changed, been added, or removed. It improves the efficiency of rendering by preventing React from unnecessarily tearing down and rebuilding components.
Why it's important:
How to use it:
const pizzas = [
{ id: 1, name: "Margherita" },
{ id: 2, name: "Pepperoni" },
{ id: 3, name: "Veggie" },
];
function PizzaList() {
return (
<ul>
{pizzas.map((pizza) => (
<li key={pizza.id}>{pizza.name}</li>
))}
</ul>
);
}
Why shouldn't we use the index of an array as the key?
Using the index as a key can cause rendering bugs because the key is not stable. If the list changes (e.g., items are reordered, added, or removed), React might reuse incorrect elements, leading to visual or data-related errors.
Problems with index-based keys:
const toppings = ["Cheese", "Pepperoni", "Mushrooms"];
function ToppingList() {
return (
<ul>
{toppings.map((topping, index) => (
<li key={index}>{topping}</li>
))}
</ul>
);
}
// If the list changes order dynamically, React might retain incorrect associations.
Are there any cases where using the index as a key is acceptable?
Using the index as a key can be acceptable in specific cases, but it should be avoided if better options are available. Acceptable scenarios include:
function StaticList() {
const items = ["One", "Two", "Three"];
return (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li> // Using index as a key for a static list.
))}
</ul>
);
}
What happens if you don't provide a key?
React will throw a warning in the console and may not optimize rendering. The absence of a key can lead to unnecessary re-rendering or incorrect updates of elements.
function NoKeyList() {
const fruits = ["Apple", "Banana", "Cherry"];
return (
<ul>
{fruits.map((fruit) => (
<li>{fruit}</li> // Missing key will throw a warning.
))}
</ul>
);
}