React Fundamentals & Lifecycle

what is react?

react is a library, not a framework

core concepts:


props

what props are

props immutability

❌ NEVER reassign props:

export const Component = ({ title }) => {
  title = title || 'Default'; // BAD - mutates props
  // ...
}

issue:

✅ derive a new variable instead:

export const Component = ({ title }) => {
  const displayTitle = title ?? 'Default'; // GOOD
  // ...
}

default values: ?? vs ||

|| - fallback on ANY falsy value

?? - fallback ONLY on null or undefined

examples:

const count = 0;
count || 10  // → 10 (0 is falsy)
count ?? 10  // → 0  (0 is not null/undefined)

const name = '';
name || 'Guest'  // → 'Guest' ('' is falsy)
name ?? 'Guest'  // → ''      ('' is not null/undefined)

rule of thumb: use ?? when 0, false, or '' are valid values.


state

what state is

when to use useState

use state when:

when NOT to use state

don't use state for:

example:

// ❌ BAD - startTime never changes
const [startTime, setStartTime] = useState(Date.now());

// ✅ GOOD - just a constant
const startTime = Date.now();

// ✅ GOOD - date changes over time
const [date, setDate] = useState(Date.now());

component lifecycle

a react function component goes through three phases:

  1. mount - component appears for the first time
  2. update - component re-renders due to state or prop changes
  3. unmount - component is removed from the UI

how lifecycle maps to useEffect

in function components, side effects are controlled with useEffect:

useEffect(() => {
  // side effect runs AFTER render

  return () => {
    // cleanup runs BEFORE next effect or on unmount
  };
}, [dependencies]);

how useEffect works internally

mount → effect runs after DOM paint
update → cleanup runs → effect runs again (if deps changed)
unmount → cleanup runs once


useEffect

what useEffect is

a hook for performing side effects in function components.

why side effects don't belong in render

render must be pure:

why?

dependency array behavior

useEffect(() => {
  // ...
}, []); // empty array → runs once on mount

useEffect(() => {
  // ...
}, [count]); // runs when count changes

useEffect(() => {
  // ...
}); // no array → runs after EVERY render (usually wrong)

effect cleanup function

useEffect(() => {
  const id = setInterval(() => {
    console.log('tick');
  }, 1000);

  // cleanup function
  return () => {
    clearInterval(id);
  };
}, []);

when cleanup runs

why cleanup matters


side effects

what counts as a side effect

why side effects must be isolated

side effects during render can:


setInterval in react (deep dive)

what setInterval is (JavaScript)

const id = setInterval(callback, delay);
clearInterval(id);

why setInterval inside render is dangerous

// ❌ DANGEROUS
function Component() {
  setInterval(() => {
    console.log('tick');
  }, 1000);

  return <div />;
}

what happens:

  1. render runs → interval created
  2. state update → render again → another interval
  3. leads to:
    • multiple intervals running
    • memory leaks
    • performance degradation

using setInterval inside useEffect

// ✅ CORRECT
useEffect(() => {
  const intervalId = setInterval(() => {
    setDate(Date.now());
  }, 1000);

  return () => {
    clearInterval(intervalId);
  };
}, []); // run once on mount

re-rendering

what causes a re-render

avoiding unnecessary re-renders


JSX & imports

JSX transformation

JSX is transformed to React.createElement calls.

before react 17:

import React from 'react'; // required

react 17+:

// no react import needed for JSX
import { useState } from 'react';

why import react is no longer required

react 17+ uses a new JSX transform that doesn't require React in scope.

when react import is still needed

import React from 'react';

// when using React.Something:
React.memo(Component);
React.forwardRef(...);
React.lazy(...);

modern JavaScript features

Date.now() vs new Date().getTime()

old way (pre-ES5, before 2009):

var timestamp = new Date().getTime(); // ❌ legacy

how it works:

  1. creates Date object in memory
  2. calls getTime() method
  3. returns number
  4. garbage collector cleans up the Date object

performance: slower - more memory allocation, GC cleanup required

modern way (ES5+):

const timestamp = Date.now(); // ✅

performance: faster - returns timestamp directly, no object allocation


common react mistakes

❌ side effects in render

// BAD
function Component() {
  setInterval(...); // creates new interval every render
  return <div />;
}

❌ reassigning props

// BAD
const Component = ({ title }) => {
  title = title || 'Default';
}

❌ using state for constants

// BAD
const [startTime, setStartTime] = useState(Date.now());
// startTime never changes - shouldn't be state

❌ forgetting effect cleanup

// BAD
useEffect(() => {
  setInterval(...);
  // missing cleanup!
}, []);

key mental models

render is not lifecycle

effects run after render

render → commit to DOM → paint → effects

cleanup prevents leaks

always clean up:

react may render more than you expect

think in data flow, not events


summary checklist