DEV Community

Cover image for JavaScript (ES6+) for React Developers: The Definitive Guide
Hamed Farazi
Hamed Farazi

Posted on Edited on

JavaScript (ES6+) for React Developers: The Definitive Guide

React is fundamentally plain JavaScript. If you ever struggle with state updates, unintended re-renders, or props drilling, the issue is rarely React itself—it is usually a missing piece of modern ECMAScript fundamentals.

  1. Modern Variables: const, let, Scoping, and Retiring var In legacy JavaScript, var was function-scoped and subject to unpredictable hoisting behaviors:
JavaScript
// The legacy problem: var leaks out of block statements
if (true) {
  var framework = "React";
}
console.log(framework); // "React" (escaped block scope)
Enter fullscreen mode Exit fullscreen mode

Modern JS introduces block scoping with let and const:

const: Enforces constant references. Variables cannot be reassigned. Use this by default (roughly 95% of the time in React components).

let: Enables reassignable block-scoped variables (ideal for counters, loops, or flags).

Temporal Dead Zone (TDZ): Unlike var, accessing let or const before declaration throws a ReferenceError rather than returning undefined.

JavaScript
/

/ Modern standard:
const API_URL = "https://api.store.com/v1";
let retryCount = 0;

if (retryCount === 0) {
  const localMessage = "Initial attempt";
  retryCount += 1;
}
// localMessage is completely inaccessible here (ReferenceError)
Enter fullscreen mode Exit fullscreen mode
  1. Arrow Functions and Lexical this Arrow functions (() => {}) give developers a concise syntax and, more crucially, lexical this scoping. They do not bind their own this, arguments, or super.

Concise Syntax & Implicit Returns
In React, implicit returns are frequently used for rendering JSX:

// Explicit return
const UserCard = (props) => {
  return <div>{props.name}</div>;
};

// Implicit return (no 'return' keyword, wrapped in parentheses)
const UserCard = ({ name }) => (
  <div className="card">
    <h3>{name}</h3>
  </div>
);
Enter fullscreen mode Exit fullscreen mode

Lexical this vs Standard Functions
In traditional functions, this is determined by how the function is invoked. With arrow functions, this is bound to the surrounding lexical context:

JavaScript
const counterService = {
  count: 0,
  start() {
    // Normal function inside setInterval would rebind 'this' to window/timeout
    setInterval(() => {
      this.count++;
      console.log(`Live Count: ${this.count}`);
    }, 1000);
  }
};
Enter fullscreen mode Exit fullscreen mode
  1. Essential Array Methods: map, filter, reduce, find, some/every


JavaScript
const products = [
  { id: "p1", title: "Wireless Mouse", price: 30, inStock: true },
  { id: "p2", title: "Mechanical Keyboard", price: 120, inStock: false },
  { id: "p3", title: "USB-C Hub", price: 45, inStock: true }
];

// 1. filter: Available items only
const available = products.filter(p => p.inStock);

// 2. map: Transform to rendered strings / components
const catalogView = available.map(p => `${p.title} - $${p.price}`);

// 3. reduce: Calculate aggregate total
const inventoryValue = products.reduce((sum, p) => sum + p.price, 0);

// 4. find: Grab exact target
const keyboard = products.find(p => p.id === "p2");

// 5. some: Availability check
const hasOutOfStock = products.some(p => !p.inStock); // true
Enter fullscreen mode Exit fullscreen mode
  1. Destructuring (Arrays & Objects) and Default Parameters

Destructuring provides syntactic shortcuts to extract nested values directly into clean variables.
Object Destructuring in Props

JavaScript

// Instead of accessing props.theme, props.title, props.isActive
function Button({ theme = "primary", title = "Submit", onClick }) {
  return (
    <button className={`btn btn-${theme}`} onClick={onClick}>
      {title}
    </button>
  );
}
Enter fullscreen mode Exit fullscreen mode

Array DestructuringArray destructuring maps variables based on positional indexing (the exact mechanism powering React's useState hook):

JavaScript
const [selectedTab, setSelectedTab] = ["overview", () => {}];
Enter fullscreen mode Exit fullscreen mode
  1. Rest and Spread Operators (...) While both use three dots (...), their intents are distinct: Spread Operator (...): Expands elements of an array or properties of an object into a new structure. Rest Parameter (...args): Condenses multiple distinct arguments into a single collected array. Immutable State Updates with Spread Never mutate React state directly; always create new copies:
JavaScript
const userProfile = { id: 101, name: "Ali", settings: { dark: true } };

// Updating user profile immutably
const updatedProfile = {
  ...userProfile,
  name: "Alireza", // overrides 'name'
  role: "Admin"     // appends new field
};

// Adding an item to an array immutably
const cart = ["Mouse", "Keyboard"];
const nextCart = [...cart, "Monitor"]; 
Enter fullscreen mode Exit fullscreen mode

Rest Parameter in Components

JavaScript
// Collect rest of props to pass through to native elements
const CustomInput = ({ label, ...nativeInputProps }) => (
  <label>
    {label}
    <input {...nativeInputProps} />
  </label>
);
Enter fullscreen mode Exit fullscreen mode
  1. Immutability: Shallow vs Deep Comparison React optimizes renders using shallow equality comparison (Object.is() / ===).

Shallow Copy / Comparison: Compares only top-level references. If an object reference hasn't changed, React assumes its internals haven't changed either.

The Mutation Trap:

JavaScript
// WRONG: Direct mutation does NOT change object reference!
const state = { count: 0, meta: { tags: ["tech"] } };
state.count = 1; 

// If passed to a memoized component or setState:
// previousState === nextState evaluated to TRUE -> NO RE-RENDER!

// RIGHT: Shallow copy creates a new top-level reference
const nextState = { ...state, count: 1 };
console.log(state === nextState); // false -> triggers re-render

// Nested reference gotcha:
// state.meta and nextState.meta still point to the EXACT SAME memory address!
// For nested mutations, you must shallow copy the inner object as well:
const fullyUpdated = {
  ...state,
  meta: {
    ...state.meta,
    tags: [...state.meta.tags, "react"]
  }
};
Enter fullscreen mode Exit fullscreen mode
  1. Async JavaScript: Promises and async/await with try/catch React lifecycles and event handlers communicate with network APIs via asynchronous promises.
JavaScript
// Standard data fetching pattern with async/await and try/catch
async function fetchProducts(category) {
  try {
    const response = await fetch(`https://api.store.com/products?category=${category}`);

    if (!response.ok) {
      throw new Error(`HTTP Error: ${response.status}`);
    }

    const data = await response.json();
    return { success: true, payload: data };
  } catch (error) {
    console.error("Fetch pipeline failed:", error.message);
    return { success: false, error: error.message };
  } finally {
    console.log("Network request completed.");
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. Modular Architecture: Named vs Default Exports JavaScript modules (ESM) enable decoupled, maintainable codebases:
JavaScript
// mathUtils.js
export const TAX_RATE = 0.09;             // Named Export
export const formatCurrency = (val) => `$${val.toFixed(2)}`; // Named Export

export default class CartEngine {}        // Default Export
Enter fullscreen mode Exit fullscreen mode
JavaScript
// Consumer.js
import CartEngine, { TAX_RATE, formatCurrency } from './mathUtils.js';
Enter fullscreen mode Exit fullscreen mode

Cheat Sheet Reference & Visuals
The premier modern interactive and open-source cheat sheets for modern JavaScript development are:

MDN Web Docs JavaScript Reference: The industry standard for official language specifications and browser compatibility tables.

Modern JavaScript Cheatsheet (mbeaudru on GitHub): Specifically tailored for developers moving to ES6+ and modern frameworks like React.

GitHub logo mbeaudru / modern-js-cheatsheet

Cheatsheet for the JavaScript knowledge you will frequently encounter in modern projects.

Modern JavaScript Cheatsheet

Modern JavaScript cheatsheet Image Credits: Ahmad Awais ⚡️

If you like this content, you can ping me or follow me on Twitter 👍

Tweet for help

Introduction

Motivation

This document is a cheatsheet for JavaScript you will frequently encounter in modern projects and most contemporary sample code.

This guide is not intended to teach you JavaScript from the ground up, but to help developers with basic knowledge who may struggle to get familiar with modern codebases (or let's say to learn React for instance) because of the JavaScript concepts used.

Besides, I will sometimes provide personal tips that may be debatable but will take care to mention that it's a personal recommendation when I do so.

Note: Most of the concepts introduced here are coming from a JavaScript language update (ES2015, often called ES6). You can find new features added by this update here; it's very well done.

Complementary Resources

When you…

Cheatography JavaScript Sheet: Fast tabular references for array manipulations, regex syntax, and function helpers.

Top comments (0)