React Way ⚛️

📋 Table of Contents


State Immutability 🔒

// Create new arrays/objects for state updates
const [users, setUsers] = useState([{id: 1, name: 'John'}])

// ➕ Adding items
setUsers([...users, {id: 2, name: 'Jane'}])
setUsers(prev => [...prev, newUser])

// ✏️ Updating items
setUsers(users.map(user => 
  user.id === 1 ? {...user, name: 'Johnny'} : user
))

// 🔄 Sorting (create new array first!)
setUsers([...users].sort((a, b) => a.name.localeCompare(b.name)))

// 🗑️ Filtering
setUsers(users.filter(user => user.id !== 1))

↑ Back to top


Event Handling 🎯

// 🎯 Use useCallback for optimization
const handleClick = useCallback((id) => {
  setItems(items => items.filter(item => item.id !== id))
}, [])

// 🎛️ State-driven UI
const [isVisible, setIsVisible] = useState(true)
<div style=>Content</div>

// 📤 Event bubbling up
const handleSubmit = (data) => {
  onSubmit?.(data) // Pass to parent
}

↑ Back to top


Conditional Rendering 🔀

// ✅ Clean conditional rendering
{user && user.isActive && <ActiveUser />}
{!user && <GuestUser />}

// 🚪 Early returns in components
if (!user) return <GuestUser />
if (!user.isActive) return <InactiveUser />
return <ActiveUser />

// 🔄 Switch-like pattern
const UserStatus = () => {
  switch(user?.status) {
    case 'premium': return <PremiumUser />
    case 'active': return <ActiveUser />
    case 'inactive': return <InactiveUser />
    default: return <GuestUser />
  }
}

// 🎯 Ternary for simple cases
{isLoading ? <Spinner /> : <Content />}

↑ Back to top


Form Handling 📝

// 🎛️ Controlled components
const [formData, setFormData] = useState({name: '', email: ''})

const handleChange = (e) => {
  setFormData(prev => ({
    ...prev,
    [e.target.name]: e.target.value
  }))
}

// 🔄 useReducer for complex forms
const formReducer = (state, action) => {
  switch(action.type) {
    case 'UPDATE_FIELD':
      return {...state, [action.field]: action.value}
    case 'RESET':
      return initialState
    case 'VALIDATE':
      return {...state, errors: validateForm(state)}
    default:
      return state
  }
}

// 📋 Form validation
const [errors, setErrors] = useState({})
const validateField = (name, value) => {
  setErrors(prev => ({
    ...prev,
    [name]: value.length < 3 ? 'Too short' : ''
  }))
}

↑ Back to top


Side Effects 🌊

// 🎬 useEffect for side effects
useEffect(() => {
  localStorage.setItem('data', JSON.stringify(data))
}, [data]) // Only when data changes

// 🚀 Mount effect (API calls)
useEffect(() => {
  fetchUserData().then(setUser)
}, []) // Only on mount

// 🧹 Cleanup side effects
useEffect(() => {
  const timer = setInterval(() => {}, 1000)
  return () => clearInterval(timer) // Cleanup
}, [])

// 👂 Event listeners
useEffect(() => {
  const handleScroll = () => setScrollY(window.scrollY)
  window.addEventListener('scroll', handleScroll)
  return () => window.removeEventListener('scroll', handleScroll)
}, [])

↑ Back to top


Performance Optimization ⚡

// 🧠 Memoization and optimization
const ExpensiveComponent = memo(({items, filter}) => {
  const filteredItems = useMemo(() => 
    items.filter(item => item.name.includes(filter))
  , [items, filter])
  
  return (
    <div>
      {filteredItems.map(item => 
        <MemoizedItem key={item.id} {...item} />
      )}
    </div>
  )
})

// 🔒 memo for component memoization
const MemoizedItem = memo(Item)

// 🎯 useCallback for function memoization
const handleClick = useCallback((id) => {
  onItemClick(id)
}, [onItemClick])

// 🚀 useMemo for expensive calculations
const expensiveValue = useMemo(() => {
  return data.reduce((acc, item) => acc + item.value, 0)
}, [data])

↑ Back to top


Children Prop 👶

// 🎁 Basic children usage
const Card = ({ children, title }) => (
  <div className="card">
    <h3>{title}</h3>
    <div className="content">
      {children}
    </div>
  </div>
)

// 📖 Usage
<Card title="User Info">
  <p>Name: John</p>
  <p>Email: john@example.com</p>
</Card>

// 🔍 Children type checking
const Modal = ({ children, isOpen }) => {
  if (!isOpen) return null
  
  return (
    <div className="modal-overlay">
      <div className="modal">
        {children}
      </div>
    </div>
  )
}

// 🎯 Render props pattern
const DataProvider = ({ children, data }) => {
  const [loading, setLoading] = useState(true)
  
  return children({ data, loading })
}

// Usage
<DataProvider>
  {({ data, loading }) => 
    loading ? <Spinner /> : <DataList data={data} />
  }
</DataProvider>

// 🔄 Children manipulation
const List = ({ children }) => {
  return (
    <ul>
      {React.Children.map(children, (child, index) => 
        <li key={index}>{child}</li>
      )}
    </ul>
  )
}

↑ Back to top


Component Composition 🎨

// 🧱 Compound components
const Tabs = ({ children, activeTab, onTabChange }) => {
  return (
    <div className="tabs">
      {children}
    </div>
  )
}

const TabList = ({ children }) => (
  <div className="tab-list">{children}</div>
)

const Tab = ({ children, id, isActive, onClick }) => (
  <button 
    className={`tab ${isActive ? 'active' : ''}`}
    onClick={() => onClick(id)}
  >
    {children}
  </button>
)

const TabPanels = ({ children }) => (
  <div className="tab-panels">{children}</div>
)

const TabPanel = ({ children, isActive }) => (
  isActive ? <div className="tab-panel">{children}</div> : null
)

// 📖 Usage
<Tabs activeTab="profile" onTabChange={setActiveTab}>
  <TabList>
    <Tab id="profile">Profile</Tab>
    <Tab id="settings">Settings</Tab>
  </TabList>
  <TabPanels>
    <TabPanel isActive={activeTab === 'profile'}>
      <ProfileContent />
    </TabPanel>
    <TabPanel isActive={activeTab === 'settings'}>
      <SettingsContent />
    </TabPanel>
  </TabPanels>
</Tabs>

// 🎯 Higher-Order Components (HOC)
const withLoading = (Component) => {
  return ({ isLoading, ...props }) => {
    if (isLoading) return <Spinner />
    return <Component {...props} />
  }
}

const EnhancedComponent = withLoading(MyComponent)

↑ Back to top


State Lifting 🔄

// 🏠 Parent manages shared state
const App = () => {
  const [user, setUser] = useState(null)
  const [cart, setCart] = useState([])
  
  return (
    <div>
      <Header user={user} cartCount={cart.length} />
      <ProductList onAddToCart={(item) => setCart([...cart, item])} />
      <Cart items={cart} onRemove={(id) => 
        setCart(cart.filter(item => item.id !== id))
      } />
    </div>
  )
}

// 📡 Sibling communication through parent
const SearchBox = ({ onSearch }) => {
  const [query, setQuery] = useState('')
  
  return (
    <input 
      value={query}
      onChange={(e) => {
        setQuery(e.target.value)
        onSearch(e.target.value) // Notify parent
      }}
    />
  )
}

const ResultsList = ({ query, results }) => {
  return (
    <div>
      <h3>Results for: {query}</h3>
      {results.map(item => <div key={item.id}>{item.name}</div>)}
    </div>
  )
}

// Parent coordinates
const SearchPage = () => {
  const [query, setQuery] = useState('')
  const [results, setResults] = useState([])
  
  const handleSearch = (searchQuery) => {
    setQuery(searchQuery)
    // Fetch results...
    setResults(/* results */)
  }
  
  return (
    <div>
      <SearchBox onSearch={handleSearch} />
      <ResultsList query={query} results={results} />
    </div>
  )
}

↑ Back to top


Custom Hooks 🎣

// 🎯 Custom hook for API calls
const useApi = (url) => {
  const [data, setData] = useState(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(null)
  
  useEffect(() => {
    fetch(url)
      .then(res => res.json())
      .then(setData)
      .catch(setError)
      .finally(() => setLoading(false))
  }, [url])
  
  return { data, loading, error }
}

// 📱 Custom hook for local storage
const useLocalStorage = (key, defaultValue) => {
  const [value, setValue] = useState(() => {
    const saved = localStorage.getItem(key)
    return saved ? JSON.parse(saved) : defaultValue
  })
  
  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value))
  }, [key, value])
  
  return [value, setValue]
}

// 🎛️ Custom hook for form handling
const useForm = (initialValues, validationRules) => {
  const [values, setValues] = useState(initialValues)
  const [errors, setErrors] = useState({})
  
  const handleChange = (name, value) => {
    setValues(prev => ({ ...prev, [name]: value }))
    
    // Validate field
    if (validationRules[name]) {
      const error = validationRules[name](value)
      setErrors(prev => ({ ...prev, [name]: error }))
    }
  }
  
  const reset = () => {
    setValues(initialValues)
    setErrors({})
  }
  
  return { values, errors, handleChange, reset }
}

// 📖 Usage
const { data, loading } = useApi('/api/users')
const [theme, setTheme] = useLocalStorage('theme', 'light')
const { values, errors, handleChange } = useForm(
  { email: '', password: '' },
  { 
    email: (value) => !value.includes('@') ? 'Invalid email' : '',
    password: (value) => value.length < 6 ? 'Too short' : ''
  }
)

↑ Back to top


Key Principles 🗝️

🎯 Think in React:
  ├── 📊 Data flows down (props)
  ├── 📤 Events bubble up (callbacks)  
  ├── 🎯 Single source of truth
  ├── 📢 Declarative > Imperative
  └── 🧱 Component composition

🔄 State Management:
  ├── useState -> simple state
  ├── useReducer -> complex state logic
  ├── useContext -> shared state (avoid prop drilling)
  ├── Custom hooks -> reusable stateful logic
  └── External libs -> global state (Redux, Zustand)

⚡ Performance:
  ├── memo() -> component memoization
  ├── useMemo() -> expensive calculations
  ├── useCallback() -> function memoization
  ├── Proper keys -> efficient list rendering
  └── Code splitting -> bundle optimization

🧹 Side Effects:
  ├── useEffect -> DOM interactions, API calls
  ├── Cleanup functions -> prevent memory leaks
  ├── Dependency arrays -> control when effects run
  └── Custom hooks -> reusable side effect logic

🎨 Component Design:
  ├── Small, focused components
  ├── Props for configuration
  ├── Children for content
  ├── Composition over inheritance
  └── Consistent naming conventions

↑ Back to top


This site uses Just the Docs, a documentation theme for Jekyll.