Türkçe

Uygulamalarınızda verimli durum yönetimi için React Context'te ustalaşın. Context'i ne zaman ve nasıl etkili bir şekilde kullanacağınızı ve yaygın tuzaklardan kaçınmayı öğrenin.

React Context: Kapsamlı Bir Rehber

React Context, component ağacının her seviyesinden prop'ları açıkça geçirmeye gerek kalmadan component'ler arasında veri paylaşmanızı sağlayan güçlü bir özelliktir. Belirli değerleri, belirli bir alt ağaçtaki tüm component'ler için kullanılabilir hale getirmenin bir yolunu sunar. Bu rehber, React Context'in ne zaman ve nasıl etkili bir şekilde kullanılacağını, en iyi uygulamaları ve kaçınılması gereken yaygın tuzakları araştırmaktadır.

Sorunu Anlamak: Prop Drilling

Karmaşık React uygulamalarında, "prop drilling" (prop delme) sorunuyla karşılaşabilirsiniz. Bu durum, bir üst component'ten derinlemesine iç içe geçmiş bir alt component'e veri aktarmanız gerektiğinde ortaya çıkar. Bunu yapmak için, veriyi ihtiyaç duymayan ara component'ler üzerinden bile geçirmeniz gerekir. Bu durum şunlara yol açabilir:

Bu basitleştirilmiş örneği ele alalım:


function App() {
  const user = { name: 'Alice', theme: 'dark' };
  return (
    <Layout user={user} />
  );
}

function Layout({ user }) {
  return (
    <Header user={user} />
  );
}

function Header({ user }) {
  return (
    <Navigation user={user} />
  );
}

function Navigation({ user }) {
  return (
    <Profile user={user} />
  );
}

function Profile({ user }) {
  return (
    <p>Welcome, {user.name}!
Theme: {user.theme}</p>
  );
}

Bu örnekte, user nesnesi, aslında yalnızca Profile component'i kullanmasına rağmen birkaç component üzerinden aşağıya doğru aktarılır. Bu, klasik bir prop drilling vakasıdır.

React Context'e Giriş

React Context, veriyi prop'lar aracılığıyla açıkça aktarmadan bir alt ağaçtaki herhangi bir component'in kullanımına sunarak prop drilling'den kaçınmanın bir yolunu sağlar. Üç ana bölümden oluşur:

React Context Ne Zaman Kullanılır?

React Context, bir React component ağacı için "global" kabul edilen verileri paylaşmak için özellikle kullanışlıdır. Bunlar şunları içerebilir:

Önemli Hususlar:

React Context Nasıl Kullanılır: Pratik Bir Örnek

Prop drilling örneğine geri dönelim ve React Context kullanarak çözelim.

1. Bir Context Oluşturun

İlk olarak, React.createContext() kullanarak bir context oluşturun. Bu context, kullanıcı verilerini tutacaktır.


// UserContext.js
import React from 'react';

const UserContext = React.createContext(null); // Varsayılan değer null veya başlangıç kullanıcı nesnesi olabilir

export default UserContext;

2. Bir Provider Oluşturun

Ardından, uygulamanızın kökünü (veya ilgili alt ağacı) UserContext.Provider ile sarmalayın. user nesnesini value prop'u olarak Provider'a geçin.


// App.js
import React from 'react';
import UserContext from './UserContext';
import Layout from './Layout';

function App() {
  const user = { name: 'Alice', theme: 'dark' };
  return (
    <UserContext.Provider value={user}>
      <Layout />
    </UserContext.Provider>
  );
}

export default App;

3. Context'i Tüketin

Artık, Profile component'i, useContext hook'unu kullanarak user verisine doğrudan context'ten erişebilir. Artık prop drilling'e gerek yok!


// Profile.js
import React, { useContext } from 'react';
import UserContext from './UserContext';

function Profile() {
  const user = useContext(UserContext);

  return (
    <p>Welcome, {user.name}!
Theme: {user.theme}</p>
  );
}

export default Profile;

Ara component'lerin (Layout, Header ve Navigation) artık user prop'unu almasına gerek yoktur.


// Layout.js, Header.js, Navigation.js
import React from 'react';

function Layout({ children }) {
  return (
    <div>
      <Header />
      <main>{children}</main>
    </div>
  );
}

function Header() {
  return (<Navigation />);
}

function Navigation() {
  return (<Profile />);
}

export default Layout;

Gelişmiş Kullanım ve En İyi Uygulamalar

1. Context'i useReducer ile Birleştirmek

Daha karmaşık durum yönetimi için, React Context'i useReducer hook'u ile birleştirebilirsiniz. Bu, durum güncellemelerini daha öngörülebilir ve sürdürülebilir bir şekilde yönetmenizi sağlar. Context durumu sağlar ve reducer, gönderilen eylemlere (action) göre durum geçişlerini yönetir.


// ThemeContext.js
import React, { createContext, useReducer } from 'react';

const ThemeContext = createContext();

const initialState = { theme: 'light' };

const themeReducer = (state, action) => {
  switch (action.type) {
    case 'TOGGLE_THEME':
      return { ...state, theme: state.theme === 'light' ? 'dark' : 'light' };
    default:
      return state;
  }
};

function ThemeProvider({ children }) {
  const [state, dispatch] = useReducer(themeReducer, initialState);

  return (
    <ThemeContext.Provider value={{ ...state, dispatch }}>
      {children}
    </ThemeContext.Provider>
  );
}

export { ThemeContext, ThemeProvider };



// ThemeToggle.js
import React, { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

function ThemeToggle() {
  const { theme, dispatch } = useContext(ThemeContext);

  return (
    <button onClick={() => dispatch({ type: 'TOGGLE_THEME' })}>
      Toggle Theme (Current: {theme})
    </button>
  );
}

export default ThemeToggle;



// App.js
import React from 'react';
import { ThemeProvider } from './ThemeContext';
import ThemeToggle from './ThemeToggle';

function App() {
  return (
    <ThemeProvider>
      <div>
        <ThemeToggle />
      </div>
    </ThemeProvider>
  );
}

export default App;

2. Çoklu Context'ler

Yönetilmesi gereken farklı türde global verileriniz varsa, uygulamanızda birden fazla context kullanabilirsiniz. Bu, endişelerinizi ayrı tutmanıza ve kod organizasyonunu iyileştirmenize yardımcı olur. Örneğin, kullanıcı kimlik doğrulaması için bir UserContext ve uygulamanın temasını yönetmek için bir ThemeContext kullanabilirsiniz.

3. Performansı Optimize Etme

Daha önce de belirtildiği gibi, context değişiklikleri tüketen component'lerde yeniden render'ları tetikleyebilir. Performansı optimize etmek için aşağıdakileri göz önünde bulundurun:

4. Context Erişimi için Özel Hook'lar Kullanma

Context değerlerine erişme ve güncelleme mantığını kapsüllemek için özel hook'lar oluşturun. Bu, kod okunabilirliğini ve sürdürülebilirliğini artırır. Örneğin:


// useTheme.js
import { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

function useTheme() {
  const context = useContext(ThemeContext);
  if (!context) {
    throw new Error('useTheme bir ThemeProvider içinde kullanılmalıdır');
  }
  return context;
}

export default useTheme;



// MyComponent.js
import React from 'react';
import useTheme from './useTheme';

function MyComponent() {
  const { theme, dispatch } = useTheme();

  return (
    <div>
      Current Theme: {theme}
      <button onClick={() => dispatch({ type: 'TOGGLE_THEME' })}>
        Toggle Theme
      </button>
    </div>
  );
}

export default MyComponent;

Kaçınılması Gereken Yaygın Tuzaklar

React Context'e Alternatifler

React Context değerli bir araç olsa da, her zaman en iyi çözüm değildir. Şu alternatifleri göz önünde bulundurun:

Sonuç

React Context, prop drilling olmadan component'ler arasında veri paylaşımı için güçlü bir özelliktir. Ne zaman ve nasıl etkili bir şekilde kullanılacağını anlamak, sürdürülebilir ve performanslı React uygulamaları oluşturmak için çok önemlidir. Bu kılavuzda belirtilen en iyi uygulamaları takip ederek ve yaygın tuzaklardan kaçınarak, kodunuzu iyileştirmek ve daha iyi bir kullanıcı deneyimi oluşturmak için React Context'ten yararlanabilirsiniz. Context kullanmaya karar vermeden önce özel ihtiyaçlarınızı değerlendirmeyi ve alternatifleri göz önünde bulundurmayı unutmayın.