Question
What do the three dots (...) do in this React JSX code, what is this syntax called, and how does it affect the props passed to Modal?
<Modal {...this.props} title="Modal heading" animation={false}>
Specifically, how are this.props, title, and animation combined when the component is rendered?
Short Answer
The ... syntax in JSX is called a spread attribute (or props spread). It takes the properties from an object and passes them to a component as individual props. In this example, this.props is spread into Modal, then the explicitly written title and animation props are applied. Because they appear later, they override matching values from this.props.
Concept
In React JSX, an expression such as:
<Component {...propsObject} />
uses a spread attribute. It copies the enumerable properties of propsObject and supplies them as props to Component.
For example:
const modalProps = {
isOpen: true,
size: "large",
title: "Old title"
};
<Modal {...modalProps} />
is approximately equivalent to:
<Modal isOpen={true} size="large" title="Old title" />
In the original code:
<Modal {...this.props} title="Modal heading" animation={false}>
React receives props from this.props, plus a fixed title and value. If already contains or , the explicitly written values win because they come later.
Mental Model
Think of a props object as a bag of labelled items:
{ size: "large", isOpen: true, title: "Old title" }
{...this.props} means: “Open this bag and place every labelled item on the Modal component.”
Then JSX adds two more labels:
title: "Modal heading"animation: false
If a label is already present, the later label replaces it. So the explicit title is like putting a new title label over the old one.
Syntax and Examples
The JSX syntax is:
<Component {...object} />
The expression after ... must evaluate to an object-like value whose properties can become props.
function Button(props) {
return <button disabled={props.disabled}>{props.children}</button>;
}
const buttonOptions = {
disabled: true,
"aria-label": "Save changes"
};
function SaveButton() {
return <Button {...buttonOptions}>Save</Button>;
}
Button receives:
disabled: truearia-label: "Save changes"children: "Save"
You can combine spread props with explicit props:
Step by Step Execution
Consider this class component example:
class ModalWrapper extends React.Component {
render() {
return (
<Modal {...this.props} title="Modal heading" animation={false}>
Settings
</Modal>
);
}
}
Suppose ModalWrapper is used like this:
<ModalWrapper isOpen={true} title="Account" animation={true} size="large" />
At render time, this.props is approximately:
{
isOpen: true,
title: "Account",
animation: true,
size: "large"
}
The JSX is processed in order:
Real World Use Cases
Spread attributes are useful when a wrapper component needs to forward props.
Reusable wrapper components
function Card({ className, ...rest }) {
return <section className={`card ${className ?? ""}`} {...rest} />;
}
A caller can provide standard attributes such as id, aria-label, and event handlers without Card manually declaring each one.
Forwarding form input props
function TextInput({ label, ...inputProps }) {
return (
<label>
{label}
<input {...inputProps} />
</label>
);
}
<TextInput label="Email" type="email" required />
Applying configuration objects
Real Codebase Usage
In real projects, props spreading is usually paired with destructuring so a component consumes its own props and forwards the rest.
function Modal({ title, animation = true, children, ...modalProps }) {
return (
<div {...modalProps} data-animation={animation}>
<h2>{title}</h2>
{children}
</div>
);
}
This pattern has clear responsibilities:
title,animation, andchildrenare used byModalitself....modalPropscontains remaining props to forward to the underlying element.
A common pattern for defaults is:
function SubmitButton(props) {
return <button type="submit" {} />;
}
Common Mistakes
Assuming ... is a React-only operator
The underlying ... is JavaScript spread syntax. JSX uses it in a special attribute position to spread object properties into component props.
Forgetting that order changes the result
const props = { title: "From object" };
<Modal title="Default" {...props} />
The title is "From object", not "Default", because the spread comes last.
To force the fixed title:
<Modal {...props} title="Default" />
Spreading an array instead of a props object
// Incorrect: array items are not named props for this purpose.
<Modal {...["open", "large"]} />
Use an object with named properties:
<Modal {...{ : , : }} />
Comparisons
| Syntax or pattern | Purpose | Example |
|---|---|---|
| JSX props spread | Pass object properties as component props | <Modal {...props} /> |
| Object spread | Copy or merge properties into a new object | const next = { ...props, title: "New" }; |
| Array spread | Expand array items where values are expected | const all = [...first, ...second]; |
| Explicit props | Name each prop directly | <Modal isOpen={true} size="large" /> |
children | Content between component tags | <Modal>Content</Modal> |
JSX spread attributes and JavaScript object spread use similar syntax, but they occur in different places:
Cheat Sheet
// Spread every property in an object as props
<Component {...props} />
// Explicit props after a spread override matching object properties
<Component {...props} title="Fixed" />
// A spread after explicit props can override them
<Component title="Default" {...props} />
// Consume selected props and forward the rest
function Input({ label, ...inputProps }) {
return <input {...inputProps} aria-label={label} />;
}
- Name: JSX spread attribute, props spread, or spread props.
- The value after
...should be an object. - Spread order is left to right; later values take precedence.
- Content between tags becomes
children. - Use destructuring to prevent internal props from reaching DOM elements.
- Prefer explicit props when clarity is more important than generic forwarding.
FAQ
What is {...this.props} called in React?
It is called a JSX spread attribute or props spread. It passes the properties in this.props to the component.
Does {...this.props} copy every prop to Modal?
It forwards the properties available in this.props. Explicit attributes written afterward can replace values with the same prop name.
Which value wins when spread props and explicit props have the same name?
The value written later wins. In <Modal {...props} title="New" />, title is "New".
Is ...props the same as React children?
No. Spread attributes pass named props from an object. Content between tags, such as <Modal>Text</Modal>, is passed separately as children.
Can I use spread props with HTML elements?
Yes. For example, <input {...inputProps} /> is common. Remove custom internal props before spreading onto a DOM element.
Why does the example use this.props?
Mini Project
Description
Build a reusable TextInput wrapper that displays a label and forwards ordinary input attributes such as type, placeholder, required, and onChange. The project demonstrates how to consume component-specific props while safely forwarding the remaining props to an HTML <input>.
Goal
Create a labelled email input that uses JSX spread attributes to forward input options.
Requirements
Include a TextInput component that accepts a label prop.
Forward all remaining props to an <input> element.
Render an email field with a placeholder and the required attribute.
Use a fixed type="email" that cannot be overridden by forwarded props.
Keep learning
Related questions
Abort Ajax Requests with jQuery jqXHR.abort()
Learn how to cancel an in-progress jQuery Ajax request with jqXHR.abort(), handle abort status safely, and avoid stale UI updates.
Access the Correct this Inside a JavaScript Callback
Learn why JavaScript this changes in callbacks and how to preserve an object context using bind, arrow functions, and event handler patterns.
Add Key-Value Pairs to JavaScript Objects
Learn how to add key-value pairs to JavaScript objects with dot and bracket notation, dynamic keys, examples, and common mistakes.