⚛️

React

Kullanıcı arayüzleri oluşturmak için JavaScript kütüphanesi.

📅 2013
👤 React Foundation (eski Meta)
📦 19.x
📄 MIT

Temel Özellikler

Virtual DOM

Diffing (fark bulma) algoritması sayesinde minimum DOM güncellemesi ile verimli render işlemi sağlar.

JSX

Kullanıcı arayüzünü tanımlamak için JavaScript ve HTML'i birleştiren JavaScript XML sözdizimi.

Bileşen Tabanlı

Yeniden kullanılabilir, birbirinden bağımsız ve kolay yönetilebilir arayüz bileşenleri oluşturulmasını sağlar.

Hooks

Sınıf bileşenleri kullanmadan durum ve yaşam döngüsü özellikleri için useState, useEffect gibi hook'lar sunar.

Tek Yönlü Veri Akışı

Verinin yukarıdan aşağıya akışı ile (one-way data binding) öngörülebilir ve kolay takip edilebilir veri yönetimi.

Büyük Ekosistem

Next.js, Redux, React Router ve sayısız üçüncü parti kütüphane desteği.

Avantajlar ve Dezavantajlar

✅ Avantajlar

  • Bileşenlerin yüksek yeniden kullanılabilirliği
  • Devasa topluluk ve destek, zengin kaynaklar
  • İş pazarında yüksek talep (en popüler frontend aracı)
  • Mobil için React Native imkanı (Learn once, write anywhere)
  • Mükemmel tarayıcı eklentileri (React DevTools)
  • Çok geniş ve aktif ekosistem

❌ Dezavantajlar

  • JSX yapısının ilk öğrenmede zorlayıcı olması
  • Basit uygulamalar için fazla boilerplate kod gerektirmesi
  • Ekosistemde (kütüphanelerde) hızlı değişimler ve uyumsuzluklar
  • Yalnızca bir UI kütüphanesi olması, ek paketlere (router vb.) ihtiyaç duyması

İnteraktif Demolar

Aşağıdaki demolar gerçek React kodunu tarayıcıda çalıştırır. Deneyin!

1. Counter (useState)

Temel durum (state) yönetimi için useState hook'unun basit bir kullanımı.

function Counter() {
  const [count, setCount] = React.useState(0);

  return (
    <div>
      <h4>Sayaç Değeri: {count}</h4>
      <button className="btn" onClick={() => setCount(count + 1)}>Arttır</button>
      <button className="btn" onClick={() => setCount(count - 1)}>Azalt</button>
      <button className="btn btn-ghost" onClick={() => setCount(0)}>Sıfırla</button>
    </div>
  );
}

const root1 = ReactDOM.createRoot(document.getElementById('demo1-root'));
root1.render(<Counter />);

2. Todo List (useState + useEffect)

Durum yönetimi ve yan etkilerle (useEffect) çalışan basit bir yapılacaklar listesi uygulaması.

function TodoApp() {
  const [todos, setTodos] = React.useState([]);
  const [text, setText] = React.useState('');
  const [count, setCount] = React.useState(0);

  React.useEffect(() => {
    setCount(todos.filter(t => !t.completed).length);
  }, [todos]);

  const addTodo = (e) => {
    e.preventDefault();
    if (!text.trim()) return;
    setTodos([...todos, { id: Date.now(), text, completed: false }]);
    setText('');
  };

  const toggleTodo = (id) => {
    setTodos(todos.map(t => t.id === id ? { ...t, completed: !t.completed } : t));
  };

  const deleteTodo = (id) => {
    setTodos(todos.filter(t => t.id !== id));
  };

  return (
    <div>
      <h4>Yapılacaklar ({count} kalan)</h4>
      <form onSubmit={addTodo} style={{display: 'flex', gap: '5px', marginBottom: '15px'}}>
        <input 
          style={{flex: 1, padding: '5px'}} 
          value={text} 
          onChange={(e) => setText(e.target.value)} 
          placeholder="Yeni görev..." 
        />
        <button type="submit" className="btn">Ekle</button>
      </form>
      <ul className="todo-list">
        {todos.map(todo => (
          <li key={todo.id} className={`todo-item ${todo.completed ? 'completed' : ''}`}>
            <span onClick={() => toggleTodo(todo.id)} style={{cursor: 'pointer', flex: 1}}>
              {todo.text}
            </span>
            <button onClick={() => deleteTodo(todo.id)} className="btn btn-ghost" style={{padding: '2px 8px'}}>Sil</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

const root2 = ReactDOM.createRoot(document.getElementById('demo2-root'));
root2.render(<TodoApp />);

3. API Data Fetching (useEffect + useState)

REST API'den asenkron veri çekme ve listeleme işlemi. Yükleniyor durumu gösterir.

function UserList() {
  const [users, setUsers] = React.useState([]);
  const [loading, setLoading] = React.useState(true);

  React.useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/users')
      .then(res => res.json())
      .then(data => {
        setUsers(data);
        setLoading(false);
      });
  }, []);

  if (loading) return <div style={{textAlign: 'center', padding: '20px'}}>Yükleniyor...</div>;

  return (
    <div>
      {users.map(user => (
        <div key={user.id} className="user-card">
          <strong>{user.name}</strong> ({user.username})<br/>
          📧 {user.email} <br/>
          🏢 {user.company.name}
        </div>
      ))}
    </div>
  );
}

const root3 = ReactDOM.createRoot(document.getElementById('demo3-root'));
root3.render(<UserList />);

4. Real-time Form Validation

Kullanıcı giriş yaptıkça çalışan anlık form doğrulama mantığı.

function RegistrationForm() {
  const [form, setForm] = React.useState({ name: '', email: '', password: '' });
  const [errors, setErrors] = React.useState({});

  const validate = (name, value) => {
    let error = '';
    if (name === 'name' && value.length < 3) error = 'İsim en az 3 karakter olmalı.';
    if (name === 'email' && !/\S+@\S+\.\S+/.test(value)) error = 'Geçerli bir email giriniz.';
    if (name === 'password' && value.length < 6) error = 'Şifre en az 6 karakter olmalı.';
    return error;
  };

  const handleChange = (e) => {
    const { name, value } = e.target;
    setForm({ ...form, [name]: value });
    setErrors({ ...errors, [name]: validate(name, value) });
  };

  const isFormValid = !Object.values(errors).some(e => e) && form.name && form.email && form.password;

  return (
    <form onSubmit={e => e.preventDefault()}>
      <div className="form-group">
        <label>İsim</label>
        <input name="name" value={form.name} onChange={handleChange} placeholder="Adınız Soyadınız" />
        {errors.name && <span className="error-msg">{errors.name}</span>}
      </div>
      <div className="form-group">
        <label>E-posta</label>
        <input name="email" value={form.email} onChange={handleChange} placeholder="[email protected]" />
        {errors.email && <span className="error-msg">{errors.email}</span>}
      </div>
      <div className="form-group">
        <label>Şifre</label>
        <input type="password" name="password" value={form.password} onChange={handleChange} placeholder="En az 6 karakter" />
        {errors.password && <span className="error-msg">{errors.password}</span>}
      </div>
      <button className="btn" disabled={!isFormValid} style={{width: '100%'}}>
        Kayıt Ol
      </button>
      {isFormValid && <div className="success-msg" style={{marginTop:'15px', textAlign:'center'}}>✅ Form geçerli, gönderilebilir!</div>}
    </form>
  );
}

const root4 = ReactDOM.createRoot(document.getElementById('demo4-root'));
root4.render(<RegistrationForm />);

Kullanım Senaryoları