Provider Pattern

The Deva SDK uses the Provider Pattern to make authentication state and methods available throughout your application without prop drilling.


What is the Provider Pattern?

The Provider Pattern is a React design pattern that uses Context to share data across your component tree without passing props manually at every level.

Without Provider (Prop Drilling):

<App user={user} login={login} logout={logout}>
  <Layout user={user} login={login} logout={logout}>
    <Sidebar user={user} logout={logout}>
      <UserProfile user={user} logout={logout} />
    </Sidebar>
  </Layout>
</App>

With Provider:

<DevaProvider>
  <App>
    <Layout>
      <Sidebar>
        <UserProfile /> {/* Access user/logout via useDeva() */}
      </Sidebar>
    </Layout>
  </App>
</DevaProvider>

How Deva SDK Uses Providers

The DevaProvider wraps your application and provides authentication context to all child components:

Any component can access authentication state without props being passed down through every level.


What DevaProvider Does

The DevaProvider manages authentication and makes it available app-wide:

Authentication Management

  • Handles OAuth flow

  • Manages access and refresh tokens

  • Automatically refreshes expired tokens

  • Stores session data

State Distribution

  • Provides authentication status

  • Shares user information

  • Exposes login/logout methods

  • Distributes access tokens

Configuration

  • Sets up API environment

  • Configures OAuth client

  • Defines redirect URLs

Learn about DevaProvider


Setting Up the Provider

Wrap your application with DevaProvider at the root:

import { DevaProvider } from "@bitplanet/deva-sdk";
import "@bitplanet/deva-sdk/style.css";

function Root() {
  return (
    <DevaProvider
      clientId={import.meta.env.VITE_DEVA_CLIENT_ID}
      redirectUri={window.location.origin}
      env={import.meta.env.VITE_DEVA_ENV}
    >
      <App />
    </DevaProvider>
  );
}

Required Props:

  • clientId - Your Deva application ID

  • redirectUri - OAuth callback URL

See quickstart guide


Accessing Provider Data

Use the useDeva() hook anywhere in your component tree:

import { useDeva } from "@bitplanet/deva-sdk";

function AnyComponent() {
  const { isAuthenticated, user, login, logout } = useDeva();

  if (!isAuthenticated) {
    return <button onClick={login}>Login</button>;
  }

  return (
    <div>
      <p>Welcome {user?.persona?.display_name}</p>
      <button onClick={logout}>Logout</button>
    </div>
  );
}

No props needed - the component directly accesses the context.

Explore useDeva hook


Benefits of This Pattern

No Prop Drilling

  • Components access data directly from context

  • No passing props through intermediate components

  • Cleaner component hierarchy

Centralized State

  • Single source of truth for authentication

  • Consistent state across the application

  • Easier to debug and maintain

Automatic Updates

  • When authentication state changes, all consuming components re-render

  • Real-time synchronization across UI

  • No manual state management needed

Component Isolation

  • Components don't need to know about authentication implementation

  • Easy to add authentication to any component

  • Better separation of concerns


Multiple Providers

While uncommon, you can use multiple DevaProviders for different authentication contexts:

<DevaProvider clientId="app1-id">
  <MainApp />
</DevaProvider>

<DevaProvider clientId="app2-id">
  <SecondaryApp />
</DevaProvider>

Each provider maintains independent authentication state.


Common Patterns

Conditional Rendering

function ProtectedRoute() {
  const { isAuthenticated, isReady } = useDeva();

  if (!isReady) return <Loading />;
  if (!isAuthenticated) return <Navigate to="/login" />;

  return <ProtectedContent />;
}

Render Props Pattern

DevaProvider also supports render props:

<DevaProvider {...config}>
  {({ isAuthenticated, user }) => (
    isAuthenticated ? (
      <Dashboard user={user} />
    ) : (
      <LandingPage />
    )
  )}
</DevaProvider>

Hook Composition

Build custom hooks on top of useDeva():

function useRequireAuth() {
  const { isAuthenticated, login } = useDeva();

  useEffect(() => {
    if (!isAuthenticated) {
      login();
    }
  }, [isAuthenticated, login]);

  return isAuthenticated;
}

Summary

The Provider Pattern in Deva SDK:

  • Wraps your application with DevaProvider

  • Manages authentication automatically

  • Distributes state via React Context

  • Provides hooks for easy access (useDeva())

  • Eliminates prop drilling for cleaner code

  • Ensures consistency across your app

This pattern makes it simple to add authentication to any component without complex state management or prop passing.


Learn More

Last updated