Spread and rest operators

Acadestine

Spread and Rest Operators

The spread (...) and rest (...) operators are powerful features introduced in ES6. They use the same syntax (...) but behave differently depending on the context. Understanding them is essential for writing concise and expressive JavaScript, especially in React.

  • Spread – expands an iterable (array, object, string) into individual elements.
  • Rest – collects multiple elements and packs them into an array or object.

The spread operator allows you to "spread" the elements of an array or object into a new array, object, or function arguments.

Spread with Arrays

const numbers = [1, 2, 3];
const newNumbers = [...numbers, 4, 5];
console.log(newNumbers); // [1, 2, 3, 4, 5]

// Copy an array
const copy = [...numbers];
console.log(copy); // [1, 2, 3]

// Concatenate arrays
const arr1 = [1, 2];
const arr2 = [3, 4];
const combined = [...arr1, ...arr2];
console.log(combined); // [1, 2, 3, 4]

Spread with Objects (ES2018+)

const user = { name: 'Alice', age: 30 };
const extendedUser = { ...user, city: 'New York' };
console.log(extendedUser); // { name: 'Alice', age: 30, city: 'New York' }

// Copy an object
const clone = { ...user };

// Override properties
const updated = { ...user, age: 31 };
console.log(updated); // { name: 'Alice', age: 31 }

Spread in Function Calls

const numbers = [1, 2, 3];
const sum = (a, b, c) => a + b + c;
console.log(sum(...numbers)); // 6

React Example: Spread is often used to pass props to components or update state immutably:

const props = { className: 'btn', disabled: false };
return <button {...props}>Click</button>;

// In useState updates
setUser(prev => ({ ...prev, age: prev.age + 1 }));

The rest operator collects multiple elements and packs them into an array or object. It's used in function parameters and destructuring.

Rest in Function Parameters

function sum(...numbers) {
  return numbers.reduce((acc, n) => acc + n, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
console.log(sum(5, 10)); // 15

Rest in Array Destructuring

const colors = ['red', 'green', 'blue', 'yellow'];
const [first, second, ...rest] = colors;
console.log(first, second, rest); // red green ['blue', 'yellow']

Rest in Object Destructuring (ES2018+)

const user = { name: 'Alice', age: 30, city: 'New York', country: 'USA' };
const { name, age, ...details } = user;
console.log(name, age); // Alice 30
console.log(details); // { city: 'New York', country: 'USA' }
Key Difference
  • Spread – "unpacks" elements (used on the right side of = or in function calls).
  • Rest – "packs" elements (used on the left side of = or in function parameters).

Spread and rest are ubiquitous in React:

  • Immutable state updates – using spread to create new objects/arrays.
  • Passing props – spread all props to a child component.
  • Handling form inputs – spreading values to update state.
  • Destructuring props – using rest to separate specific props from the rest.
  • Hooks – useReducer often uses spread for immutability.
// Immutable update in useState
const [person, setPerson] = useState({ name: 'John', age: 25 });
const updateAge = () => {
  setPerson(prev => ({ ...prev, age: prev.age + 1 }));
};

// Passing props with spread
const Button = ({ size, ...rest }) => (
  <button className={`btn-${size}`} {...rest}>Click</button>
);
// Now Button can accept any other props like onClick, disabled, etc.

// Using rest to extract specific props
const UserCard = ({ name, age, ...otherProps }) => (
  <div {...otherProps}>
    <h2>{name}</h2>
    <p>{age}</p>
  </div>
);

Spread works with any iterable, including strings and Sets.

// String to array
const chars = [...'hello'];
console.log(chars); // ['h','e','l','l','o']

// Set to array (removes duplicates)
const numbers = [1, 2, 2, 3];
const unique = [...new Set(numbers)];
console.log(unique); // [1, 2, 3]

  • Spread (...) – expands elements; used for copying, merging, and function arguments.
  • Rest (...) – collects elements; used in function parameters and destructuring.
  • Both are essential for immutable patterns in React.
  • They make code more readable and reduce boilerplate.
Key Takeaway

"Spread to expand, rest to collect – they are two sides of the same coin and are indispensable in modern JavaScript and React."

Happy coding!