# Top 30 Pertanyaan Wawancara React: Panduan Lengkap untuk Sukses > 30 pertanyaan wawancara React paling sering ditanyakan pada 2026. Jawaban rinci, contoh kode, dan tips untuk mendapatkan posisi React developer. - Published: 2026-01-31 - Updated: 2026-04-21 - Author: SharpSkill - Tags: react interview, frontend interview, react questions, javascript, technical interview - Reading time: 18 min --- Wawancara teknis React mengukur pemahaman terhadap konsep dasar, pola lanjutan, dan praktik terbaik. Panduan ini menyajikan 30 pertanyaan yang paling sering muncul, lengkap dengan jawaban rinci dan contoh kode untuk persiapan yang efektif. > **Saran persiapan** > > Pertanyaan-pertanyaan ini disusun berdasarkan tingkat kesulitan. Menguasai dasar sebelum beralih ke konsep lanjutan memungkinkan persiapan yang lebih terstruktur. ## Dasar-dasar React ### 1. Apa itu Virtual DOM dan mengapa React menggunakannya? Virtual DOM adalah representasi JavaScript yang ringan dari DOM sebenarnya. React memanfaatkan abstraksi ini untuk mengoptimalkan pembaruan antarmuka. Prosesnya berlangsung dalam tiga langkah: React pertama-tama membuat salinan virtual dari DOM, kemudian membandingkan salinan tersebut dengan versi sebelumnya ketika terjadi perubahan (algoritma diffing), lalu menerapkan hanya modifikasi yang diperlukan pada DOM sebenarnya (rekonsiliasi). ```jsx // Simplified example of the concept // When state changes, React doesn't recreate the entire DOM function Counter() { const [count, setCount] = useState(0) // Only the span containing count will be updated in the real DOM // The rest of the component is untouched return (

Counter

{count}
) } ``` Pendekatan ini menghindari operasi DOM yang mahal dan memungkinkan pembaruan yang cepat bahkan untuk antarmuka yang kompleks. ### 2. Apa perbedaan antara komponen fungsional dan komponen kelas? Komponen fungsional adalah fungsi JavaScript yang menerima props dan mengembalikan JSX. Sejak React 16.8, hooks memungkinkan penggunaan state dan siklus hidup dalam komponen fungsional. ```jsx // Functional component (recommended) // More concise, easier to test, supports hooks function Welcome({ name }) { const [visits, setVisits] = useState(0) useEffect(() => { setVisits(v => v + 1) }, []) return

Hello {name}, visit #{visits}

} // Class component (legacy) // More verbose, requires this binding class WelcomeClass extends React.Component { state = { visits: 0 } componentDidMount() { this.setState(prev => ({ visits: prev.visits + 1 })) } render() { return

Hello {this.props.name}, visit #{this.state.visits}

} } ``` Komponen fungsional kini menjadi standar. Komponen kelas tetap didukung tetapi tidak lagi direkomendasikan untuk proyek baru. ### 3. Bagaimana JSX bekerja? JSX merupakan ekstensi sintaks JavaScript yang memungkinkan penulisan markup di dalam kode. JSX bukanlah HTML, melainkan JavaScript dalam bentuk yang disamarkan. ```jsx // What we write (JSX) const element = (

Title

Paragraph

) // What Babel compiles (pure JavaScript) const element = React.createElement( 'div', { className: 'container' }, React.createElement('h1', null, 'Title'), React.createElement('p', null, 'Paragraph') ) ``` Perbedaan dengan HTML mencakup: `className` alih-alih `class`, `htmlFor` alih-alih `for`, camelCase untuk atribut (`onClick`, `tabIndex`), dan keharusan menutup tag self-closing. ### 4. Apa perbedaan state dan props? Props adalah data yang diteruskan dari komponen induk ke komponen anak. Props bersifat hanya baca. State merupakan kondisi internal suatu komponen yang dapat diubah melalui setter. ```jsx // UserCard.jsx // name and role are props (immutable) function UserCard({ name, role }) { // isExpanded is state (mutable) const [isExpanded, setIsExpanded] = useState(false) return (

{name}

{role}

{/* Modifying state triggers a re-render */} {isExpanded && }
) } // Usage ``` Aturan mendasarnya: props mengalir ke bawah (induk → anak), sedangkan state bersifat lokal untuk setiap komponen. ### 5. Mengapa key penting dalam daftar? Key membantu React mengidentifikasi elemen mana yang berubah, ditambahkan, atau dihapus dalam suatu daftar. Tanpa key yang unik dan stabil, React bisa menunjukkan perilaku yang tidak terduga. ```jsx // ❌ Bad practice: index as key // Problem: if order changes, React loses tracking {items.map((item, index) => ( ))} // ✅ Good practice: unique and stable identifier {items.map(item => ( ))} // Concrete example of the problem with indices function TodoList() { const [todos, setTodos] = useState([ { id: 1, text: 'Learn React' }, { id: 2, text: 'Create a project' } ]) // When deleting the first element with key={index} // React will think element 0's content changed // instead of understanding an element was removed return (
    {todos.map(todo => (
  • {todo.text}
  • ))}
) } ``` ## React Hooks ### 6. Jelaskan useState dan jebakan umumnya `useState` mengelola state lokal dalam komponen fungsional. Setter dapat menerima sebuah nilai atau sebuah fungsi pembaru. ```jsx // Declaration with initial value const [count, setCount] = useState(0) // ❌ Pitfall: multiple updates in the same cycle function increment() { setCount(count + 1) // count = 0, sets 1 setCount(count + 1) // count = 0 still, sets 1 setCount(count + 1) // count = 0 still, sets 1 // Final result: 1 (not 3) } // ✅ Solution: use the update function function incrementCorrect() { setCount(prev => prev + 1) // 0 → 1 setCount(prev => prev + 1) // 1 → 2 setCount(prev => prev + 1) // 2 → 3 // Final result: 3 } // ❌ Pitfall: object mutation const [user, setUser] = useState({ name: 'Alice', age: 25 }) user.age = 26 // Direct mutation, no re-render // ✅ Solution: create a new object setUser({ ...user, age: 26 }) // or setUser(prev => ({ ...prev, age: 26 })) ``` ### 7. Bagaimana useEffect bekerja dengan array dependensinya? `useEffect` menjalankan efek samping setelah render. Array dependensi mengendalikan kapan efek tersebut dieksekusi. ```jsx // Executed on every render (rare, usually avoid) useEffect(() => { console.log('Render completed') }) // Executed only on mount (equivalent to componentDidMount) useEffect(() => { console.log('Component mounted') // Cleanup on unmount (equivalent to componentWillUnmount) return () => { console.log('Component unmounted') } }, []) // Executed when userId changes useEffect(() => { async function fetchUser() { const response = await fetch(`/api/users/${userId}`) const data = await response.json() setUser(data) } fetchUser() }, [userId]) // ❌ Missing dependency - subtle bug useEffect(() => { const timer = setInterval(() => { setCount(count + 1) // count is "captured" at its initial value }, 1000) return () => clearInterval(timer) }, []) // count is missing from dependencies // ✅ Fix with update function useEffect(() => { const timer = setInterval(() => { setCount(prev => prev + 1) // No need for count in deps }, 1000) return () => clearInterval(timer) }, []) ``` > **Aturan ESLint** > > Sebaiknya `eslint-plugin-react-hooks` selalu diaktifkan untuk mendeteksi dependensi yang hilang. Aturan ini mencegah banyak bug yang sulit didiagnosis. ### 8. Kapan sebaiknya menggunakan useMemo dan useCallback? Kedua hook ini memungkinkan memoisasi agar tidak terjadi perhitungan ulang atau pembuatan ulang yang tidak perlu. Namun, keduanya sebaiknya tidak digunakan secara berlebihan. ```jsx // useMemo: memoizes a computed value function ProductList({ products, filter }) { // Recalculated only if products or filter change const filteredProducts = useMemo(() => { console.log('Filtering...') return products.filter(p => p.category === filter) }, [products, filter]) return
    {filteredProducts.map(p =>
  • {p.name}
  • )}
} // useCallback: memoizes a function function ParentComponent() { const [count, setCount] = useState(0) // Without useCallback, handleClick is recreated on every render // Causing unnecessary re-renders of ExpensiveChild const handleClick = useCallback((id) => { console.log('Clicked:', id) }, []) // Empty deps = stable function return ( <> {count} {/* React.memo on ExpensiveChild for this to be effective */} ) } // ❌ Over-optimization: not needed here const SimpleComponent = () => { // This calculation is trivial, useMemo adds overhead const doubled = useMemo(() => 2 * 2, []) return {doubled} } ``` Kedua hook ini sebaiknya digunakan hanya ketika ditemukan masalah performa nyata atau untuk menjaga stabilitas referensi yang diteruskan ke komponen yang dimemoisasi. ### 9. Bagaimana useRef bekerja dan apa saja kasus penggunaannya? `useRef` menciptakan referensi yang dapat berubah dan bertahan antar-render tanpa memicu render ulang ketika nilainya berubah. ```jsx // Case 1: Access a DOM element function TextInput() { const inputRef = useRef(null) const focusInput = () => { inputRef.current.focus() } return ( <> ) } // Case 2: Store a mutable value without re-render function Timer() { const [seconds, setSeconds] = useState(0) const intervalRef = useRef(null) const start = () => { // Store the interval ID to be able to stop it intervalRef.current = setInterval(() => { setSeconds(s => s + 1) }, 1000) } const stop = () => { clearInterval(intervalRef.current) } return (
{seconds}s
) } // Case 3: Keep the previous value function usePrevious(value) { const ref = useRef() useEffect(() => { ref.current = value }, [value]) return ref.current } ``` ### 10. Jelaskan useContext dan kapan menggunakannya `useContext` memberikan akses ke React context tanpa harus menurunkan props berlapis-lapis. Ideal untuk data global seperti tema atau pengguna yang sedang login. ```jsx // 1. Create the context const ThemeContext = createContext({ theme: 'light', toggleTheme: () => {} }) // 2. Create the provider function ThemeProvider({ children }) { const [theme, setTheme] = useState('light') const toggleTheme = useCallback(() => { setTheme(prev => prev === 'light' ? 'dark' : 'light') }, []) // Memoize the value to avoid unnecessary re-renders const value = useMemo(() => ({ theme, toggleTheme }), [theme, toggleTheme]) return ( {children} ) } // 3. Use the context function ThemedButton() { const { theme, toggleTheme } = useContext(ThemeContext) return ( ) } // 4. Wrap the application function App() { return (