BelajarKoding Logobelajarkoding

Platform belajar web development Indonesia. Artikel, cheat sheets, roadmap, dan code challenges untuk developer Indonesia.

Navigasi

  • Artikel
  • Cheat Sheets
  • Roadmap
  • Challenges
  • Pricing
  • Search

Produk Lain

  • JagoHermes
  • KelasClaude
  • KilatKoding
  • BelajarVibeCoding
  • JualanKoding

Support

  • Privacy Policy
  • Terms of Service
  • Email

© 2026 BelajarKoding. All rights reserved.

Galih PratamaBagian dari ekosistem Galih Pratama
belajarkoding LogobyGalih Pratama
RoadmapArtikelCheat SheetsChallengesUpgrade
belajarkoding LogobyGalih Pratama
RoadmapArtikelCheat SheetsChallengesUpgrade
belajarkoding LogobyGalih Pratama
RoadmapArtikelCheat SheetsChallengesUpgrade

Daftar Isi

Getting StartedInstallationBasic ComponentJSXJSX BasicsStylingComponents & PropsFunction ComponentsChildren PropState dengan useStateBasic UsageMultiple State VariablesState dengan ObjectState dengan ArrayEffects dengan useEffectBasic UsageCleanupFetching DataOther HooksuseRefuseContextuseReduceruseMemouseCallbackReact 19 Featuresuse HookActionsuseFormStatususeOptimisticServer ComponentsMetadata (React 19)Custom HooksCreating Custom HooksuseFetch HookPerformance OptimizationReact.memoReact.lazyuseTransitionuseDeferredValueError BoundariesPortalsRefs dengan forwardRefBest PracticesComponent OrganizationAvoid Common MistakesKey Prop
ReactJavaScriptFrontend

React 19 Cheat Sheet

Referensi lengkap React 19. Hooks, Server Components, Actions, Compiler, dan fitur terbaru. Perfect buat modern React development.

JavaScript11 min read2.158 kata
Silakan login atau daftar untuk membaca cheat sheet ini.

#Getting Started

Panduan awal untuk memulai pengembangan aplikasi React dengan setup dan komponen dasar.

#Installation

Cara menginstall React menggunakan berbagai tool modern seperti Vite atau Next.js.

bash
# Create React App (gak direkomendasi lagi)
npx create-react-app my-app
 
# Vite (recommended)
npm create vite@latest my-app -- --template react
 
# Next.js (production-ready)
npx create-next-app@latest
 
# Remix
npx create-remix@latest

#Basic Component

Cara membuat komponen React dasar dengan function component dan props.

jsx
// Function Component
function Welcome() {
 return <h1>Hello, World!</h1>
}
 
// Dengan props
function Welcome({ name }) {
 return <h1>Hello, {name}!</h1>
}
 
// Export
export default Welcome

#JSX

Sintaks JSX yang memungkinkan menulis HTML dalam JavaScript untuk membuat UI React.

#JSX Basics

Dasar-dasar JSX termasuk expressions, attributes, children, dan conditional rendering.

jsx
// Expression dalam JSX
const name = 'Budi'
const element = <h1>Hello, {name}</h1>
 
// Attributes
const element = <img src={imageUrl} alt="Description" />
 
// Children
const element = (
 <div>
  <h1>Title</h1>
  <p>Paragraph</p>
 </div>
)
 
// Fragment
return (
 <>
  <h1>Title</h1>
  <p>Paragraph</p>
 </>
)
 
// Conditional rendering
{isLoggedIn && <p>Welcome back!</p>}
{isLoggedIn ? <LogoutButton /> : <LoginButton />}
 
// List rendering
{items.map(item => (
 <li key={item.id}>{item.name}</li>
))}

#Styling

Berbagai cara menambahkan styling pada komponen React dengan inline styles dan className.

jsx
// Inline styles
<div style={{ color: 'red', fontSize: '16px' }}>Text</div>
 
// className
<div className="container">Content</div>
 
// Conditional className
<div className={isActive ? 'active' : 'inactive'}>
 
// Multiple classes
<div className={`btn ${isActive ? 'active' : ''}`}>

#Components & Props

Cara membuat dan menggunakan komponen dengan props untuk data flow dalam React.

#Function Components

Komponen function modern dengan berbagai cara menangani props dan default values.

jsx
function Greeting({ name, age }) {
 return (
  <div>
   <h1>Hello, {name}</h1>
   <p>Age: {age}</p>
  </div>
 )
}
 
// Default props
function Greeting({ name = 'Guest', age = 0 }) {
 return <h1>Hello, {name}</h1>
}
 
// Destructuring dengan rest
function Button({ children, ...props }) {
 return <button {...props}>{children}</button>
}
 
// Usage
<Button className="primary" onClick={handleClick}>
 Click me
</Button>

#Children Prop

Cara menggunakan children prop untuk membuat komponen yang fleksibel dengan konten dinamis.

jsx
function Card({ children }) {
 return (
  <div className="card">
   {children}
  </div>
 )
}
 
// Usage
<Card>
 <h2>Title</h2>
 <p>Content</p>
</Card>

#State dengan useState

Mengelola state lokal dalam komponen React menggunakan hook useState.

#Basic Usage

Cara dasar menggunakan useState untuk state sederhana.

jsx
import { useState } from 'react'
 
function Counter() {
 const [count, setCount] = useState(0)
 
 return (
  <div>
   <p>Count: {count}</p>
   <button onClick={() => setCount(count + 1)}>
    Increment
   </button>
  </div>
 )
}

#Multiple State Variables

Mengelola beberapa state yang berbeda dalam satu komponen.

jsx
function Form() {
 const [name, setName] = useState('')
 const [email, setEmail] = useState('')
 const [age, setAge] = useState(0)
 
 return (
  <form>
   <input
    value={name}
    onChange={(e) => setName(e.target.value)}
   />
   <input
    value={email}
    onChange={(e) => setEmail(e.target.value)}
   />
  </form>
 )
}

#State dengan Object

Cara mengelola state yang berupa object dengan spread operator.

jsx
function UserForm() {
 const [user, setUser] = useState({
  name: '',
  email: '',
  age: 0
 })
 
 function handleChange(e) {
  setUser({
   ...user,
   [e.target.name]: e.target.value
  })
 }
 
 return (
  <input
   name="name"
   value={user.name}
   onChange={handleChange}
  />
 )
}

#State dengan Array

Teknik mengelola state array dengan operasi add, remove, dan update.

jsx
function TodoList() {
 const [todos, setTodos] = useState([])
 
 // Add
 function addTodo(text) {
  setTodos([...todos, { id: Date.now(), text }])
 }
 
 // Remove
 function removeTodo(id) {
  setTodos(todos.filter(todo => todo.id !== id))
 }
 
 // Update
 function updateTodo(id, newText) {
  setTodos(todos.map(todo =>
   todo.id === id ? { ...todo, text: newText } : todo
  ))
 }
}

#Effects dengan useEffect

Hook untuk menjalankan side effects dalam komponen function.

#Basic Usage

Cara dasar menggunakan useEffect untuk berbagai skenario.

jsx
import { useEffect } from 'react'
 
function Example() {
 const [count, setCount] = useState(0)
 
 // Run setelah every render
 useEffect(() => {
  document.title = `Count: ${count}`
 })
 
 // Run hanya sekali (on mount)
 useEffect(() => {
  console.log('Component mounted')
 }, [])
 
 // Run kalo dependencies berubah
 useEffect(() => {
  console.log('Count changed:', count)
 }, [count])
}

#Cleanup

Cara menggunakan cleanup function untuk membersihkan effects.

jsx
useEffect(() => {
 const timer = setInterval(() => {
  console.log('Tick')
 }, 1000)
 
 // Cleanup function
 return () => {
  clearInterval(timer)
 }
}, [])

#Fetching Data

jsx
function UserProfile({ userId }) {
 const [user, setUser] = useState(null)
 const [loading, setLoading] = useState(true)
 
 useEffect(() => {
  let cancelled = false
 
  async function fetchUser() {
   setLoading(true)
   try {
    const response = await fetch(`/api/users/${userId}`)
    const data = await response.json()
    if (!cancelled) {
     setUser(data)
    }
   } catch (error) {
    console.error(error)
   } finally {
    if (!cancelled) {
     setLoading(false)
    }
   }
  }
 
  fetchUser()
 
  return () => {
   cancelled = true
  }
 }, [userId])
 
 if (loading) return <div>Loading...</div>
 return <div>{user.name}</div>
}

#Other Hooks

#useRef

jsx
import { useRef } from 'react'
 
function TextInput() {
 const inputRef = useRef(null)
 
 function handleClick() {
  inputRef.current.focus()
 }
 
 return (
  <>
   <input ref={inputRef} />
   <button onClick={handleClick}>Focus</button>
  </>
 )
}
 
// Store mutable value
function Timer() {
 const intervalRef = useRef(null)
 
 function start() {
  intervalRef.current = setInterval(() => {
   console.log('Tick')
  }, 1000)
 }
 
 function stop() {
  clearInterval(intervalRef.current)
 }
}

#useContext

jsx
import { createContext, useContext, useState } from 'react'
 
// Create context
const ThemeContext = createContext()
 
// Provider
function App() {
 const [theme, setTheme] = useState('light')
 
 return (
  <ThemeContext.Provider value={{ theme, setTheme }}>
   <Page />
  </ThemeContext.Provider>
 )
}
 
// Consumer
function ThemedButton() {
 const { theme, setTheme } = useContext(ThemeContext)
 
 return (
  <button
   style={{ background: theme === 'dark' ? '#333' : '#fff' }}
   onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
  >
   Toggle Theme
  </button>
 )
}

#useReducer

jsx
import { useReducer } from 'react'
 
function reducer(state, action) {
 switch (action.type) {
  case 'increment':
   return { count: state.count + 1 }
  case 'decrement':
   return { count: state.count - 1 }
  case 'reset':
   return { count: 0 }
  default:
   throw new Error()
 }
}
 
function Counter() {
 const [state, dispatch] = useReducer(reducer, { count: 0 })
 
 return (
  <>
   <p>Count: {state.count}</p>
   <button onClick={() => dispatch({ type: 'increment' })}>+</button>
   <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
   <button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
  </>
 )
}

#useMemo

jsx
import { useMemo } from 'react'
 
function ExpensiveComponent({ items }) {
 // Compute heavy calculation
 const total = useMemo(() => {
  console.log('Calculating...')
  return items.reduce((sum, item) => sum + item.price, 0)
 }, [items])
 
 return <div>Total: {total}</div>
}

#useCallback

jsx
import { useCallback } from 'react'
 
function Parent() {
 const [count, setCount] = useState(0)
 
 // Memoize function
 const handleClick = useCallback(() => {
  setCount(c => c + 1)
 }, [])
 
 return <Child onClick={handleClick} />
}
 
// Child gak re-render kalo handleClick gak berubah
const Child = React.memo(({ onClick }) => {
 console.log('Child rendered')
 return <button onClick={onClick}>Click</button>
})

#React 19 Features

#use Hook

jsx
import { use } from 'react'
 
// Read promise
function UserProfile({ userPromise }) {
 const user = use(userPromise)
 return <div>{user.name}</div>
}
 
// Read context
function ThemedButton() {
 const theme = use(ThemeContext)
 return <button>{theme}</button>
}
 
// Conditional use (bisa di dalam if!)
function Component({ condition }) {
 if (condition) {
  const value = use(SomeContext)
  return <div>{value}</div>
 }
 return null
}

#Actions

jsx
import { useActionState } from 'react'
 
function UpdateNameForm() {
 async function updateName(prevState, formData) {
  const name = formData.get('name')
 
  try {
   await saveToDatabase(name)
   return { success: true, message: 'Saved!' }
  } catch (error) {
   return { success: false, message: error.message }
  }
 }
 
 const [state, formAction, isPending] = useActionState(
  updateName,
  { success: false, message: '' }
 )
 
 return (
  <form action={formAction}>
   <input name="name" disabled={isPending} />
   <button disabled={isPending}>
    {isPending ? 'Saving...' : 'Save'}
   </button>
   {state.message && <p>{state.message}</p>}
  </form>
 )
}

#useFormStatus

jsx
import { useFormStatus } from 'react-dom'
 
function SubmitButton() {
 const { pending } = useFormStatus()
 
 return (
  <button disabled={pending}>
   {pending ? 'Submitting...' : 'Submit'}
  </button>
 )
}
 
// Harus di dalam <form>
function MyForm() {
 return (
  <form action={handleSubmit}>
   <input name="text" />
   <SubmitButton />
  </form>
 )
}

#useOptimistic

jsx
import { useOptimistic } from 'react'
 
function TodoList({ todos }) {
 const [optimisticTodos, addOptimisticTodo] = useOptimistic(
  todos,
  (state, newTodo) => [...state, { ...newTodo, pending: true }]
 )
 
 async function handleSubmit(formData) {
  const newTodo = { id: Date.now(), text: formData.get('text') }
 
  // Update UI optimistically
  addOptimisticTodo(newTodo)
 
  // Send to server
  await saveTodo(newTodo)
 }
 
 return (
  <>
   {optimisticTodos.map(todo => (
    <li key={todo.id} style={{ opacity: todo.pending ? 0.5 : 1 }}>
     {todo.text}
    </li>
   ))}
   <form action={handleSubmit}>
    <input name="text" />
    <button>Add</button>
   </form>
  </>
 )
}

#Server Components

jsx
// Server Component (default di Next.js App Router)
async function UserList() {
 // Fetch langsung di component
 const users = await fetch('https://api.example.com/users')
  .then(r => r.json())
 
 return (
  <ul>
   {users.map(user => (
    <li key={user.id}>{user.name}</li>
   ))}
  </ul>
 )
}
 
// Client Component
'use client' // Directive
 
import { useState } from 'react'
 
function Counter() {
 const [count, setCount] = useState(0)
 return <button onClick={() => setCount(count + 1)}>{count}</button>
}

#Metadata (React 19)

jsx
// Component bisa render metadata langsung
function BlogPost({ post }) {
 return (
  <>
   <title>{post.title}</title>
   <meta name="description" content={post.excerpt} />
   <meta property="og:title" content={post.title} />
 
   <article>
    <h1>{post.title}</h1>
    <p>{post.content}</p>
   </article>
  </>
 )
}

#Custom Hooks

#Creating Custom Hooks

jsx
// useLocalStorage
function useLocalStorage(key, initialValue) {
 const [value, setValue] = useState(() => {
  const item = localStorage.getItem(key)
  return item ? JSON.parse(item) : initialValue
 })
 
 useEffect(() => {
  localStorage.setItem(key, JSON.stringify(value))
 }, [key, value])
 
 return [value, setValue]
}
 
// Usage
function App() {
 const [name, setName] = useLocalStorage('name', 'Guest')
 
 return (
  <input
   value={name}
   onChange={(e) => setName(e.target.value)}
  />
 )
}

#useFetch Hook

jsx
function useFetch(url) {
 const [data, setData] = useState(null)
 const [loading, setLoading] = useState(true)
 const [error, setError] = useState(null)
 
 useEffect(() => {
  let cancelled = false
 
  async function fetchData() {
   try {
    const response = await fetch(url)
    const json = await response.json()
    if (!cancelled) {
     setData(json)
     setLoading(false)
    }
   } catch (e) {
    if (!cancelled) {
     setError(e)
     setLoading(false)
    }
   }
  }
 
  fetchData()
 
  return () => {
   cancelled = true
  }
 }, [url])
 
 return { data, loading, error }
}
 
// Usage
function UserProfile() {
 const { data, loading, error } = useFetch('/api/user')
 
 if (loading) return <div>Loading...</div>
 if (error) return <div>Error: {error.message}</div>
 return <div>{data.name}</div>
}

#Performance Optimization

#React.memo

jsx
import { memo } from 'react'
 
// Component cuma re-render kalo props berubah
const ExpensiveComponent = memo(function ExpensiveComponent({ value }) {
 console.log('Rendering...')
 return <div>{value}</div>
})
 
// Dengan custom comparison
const Component = memo(
 function Component({ user }) {
  return <div>{user.name}</div>
 },
 (prevProps, nextProps) => {
  return prevProps.user.id === nextProps.user.id
 }
)

#React.lazy

jsx
import { lazy, Suspense } from 'react'
 
// Code splitting
const HeavyComponent = lazy(() => import('./HeavyComponent'))
 
function App() {
 return (
  <Suspense fallback={<div>Loading...</div>}>
   <HeavyComponent />
  </Suspense>
 )
}

#useTransition

jsx
import { useState, useTransition } from 'react'
 
function SearchResults() {
 const [query, setQuery] = useState('')
 const [results, setResults] = useState([])
 const [isPending, startTransition] = useTransition()
 
 function handleChange(e) {
  setQuery(e.target.value)
 
  // Mark expensive update as low priority
  startTransition(() => {
   setResults(filterResults(e.target.value))
  })
 }
 
 return (
  <>
   <input value={query} onChange={handleChange} />
   {isPending && <div>Searching...</div>}
   <ResultsList results={results} />
  </>
 )
}

#useDeferredValue

jsx
import { useDeferredValue } from 'react'
 
function SearchPage({ query }) {
 const deferredQuery = useDeferredValue(query)
 
 // Results akan update dengan delay
 return <SearchResults query={deferredValue} />
}

#Error Boundaries

jsx
class ErrorBoundary extends React.Component {
 constructor(props) {
  super(props)
  this.state = { hasError: false }
 }
 
 static getDerivedStateFromError(error) {
  return { hasError: true }
 }
 
 componentDidCatch(error, errorInfo) {
  console.error('Error:', error, errorInfo)
 }
 
 render() {
  if (this.state.hasError) {
   return <h1>Something went wrong.</h1>
  }
 
  return this.props.children
 }
}
 
// Usage
<ErrorBoundary>
 <MyComponent />
</ErrorBoundary>

#Portals

jsx
import { createPortal } from 'react-dom'
 
function Modal({ children }) {
 return createPortal(
  <div className="modal">
   {children}
  </div>,
  document.body
 )
}

#Refs dengan forwardRef

jsx
import { forwardRef } from 'react'
 
const Input = forwardRef((props, ref) => {
 return <input ref={ref} {...props} />
})
 
// Usage
function Parent() {
 const inputRef = useRef(null)
 
 return <Input ref={inputRef} />
}

#Best Practices

#Component Organization

jsx
// 1. Imports
import { useState, useEffect } from 'react'
 
// 2. Component
function MyComponent({ prop1, prop2 }) {
 // 3. State
 const [state, setState] = useState(0)
 
 // 4. Effects
 useEffect(() => {
  // ...
 }, [])
 
 // 5. Event handlers
 function handleClick() {
  // ...
 }
 
 // 6. Render
 return (
  <div onClick={handleClick}>
   {state}
  </div>
 )
}
 
// 7. Export
export default MyComponent

#Avoid Common Mistakes

jsx
// Don't mutate state directly
const [items, setItems] = useState([])
items.push(newItem) // Bad!
 
// Create new array
setItems([...items, newItem])
 
// Don't call hooks conditionally
if (condition) {
 useState(0) // Bad!
}
 
// Always call at top level
const [state, setState] = useState(0)
 
// Don't forget dependencies
useEffect(() => {
 doSomething(prop)
}, []) // Missing prop!
 
// Include all dependencies
useEffect(() => {
 doSomething(prop)
}, [prop])

#Key Prop

jsx
// Index as key (avoid if possible)
{items.map((item, index) => (
 <div key={index}>{item}</div>
))}
 
// Unique ID as key
{items.map(item => (
 <div key={item.id}>{item.name}</div>
))}

Baca Cheat Sheet Lengkap

Login atau daftar akun gratis untuk membaca cheat sheet ini.

LoginDaftar Gratis
Share: