Sensrik docs

← All examples

React

Functional component with hooks. Works in Vite, Next.js, Create React App, Remix, or anywhere React 18+ runs. No state library needed.

Install

The SDK isn't on npm yet. Save the module and its type declarations into your project — it's one dependency-free ES module, so there's nothing else to install.

curl -o src/lib/sensrik.js   https://docs.sensrik.com/sensrik.js
curl -o src/lib/sensrik.d.ts https://docs.sensrik.com/sensrik.d.ts

A reusable Sensrik singleton

// src/lib/sensrik.ts
import { Sensrik } from './sensrik.js';

const STORAGE_KEY = 'sensrik.session';

function loadStored() {
  try { return JSON.parse(localStorage.getItem(STORAGE_KEY) || 'null'); }
  catch { return null; }
}

const stored = loadStored();

export const sensrik = new Sensrik({
  accessToken: stored?.accessToken,
  refreshToken: stored?.refreshToken,
  onTokenRefreshed: (tokens) => localStorage.setItem(STORAGE_KEY, JSON.stringify(tokens)),
});

export function clearSession() {
  localStorage.removeItem(STORAGE_KEY);
}

A login form

// src/components/LoginForm.tsx
import { useState } from 'react';
import { sensrik } from '../lib/sensrik';

export function LoginForm({ onSuccess }: { onSuccess: () => void }) {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setError(null);
    setBusy(true);
    try {
      await sensrik.auth.login(email, password);
      onSuccess();
    } catch (err: any) {
      setError(err?.status === 401 ? 'Invalid email or password.' : err?.message);
    } finally {
      setBusy(false);
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      {error && <div className="error">{error}</div>}
      <input type="email" value={email} onChange={e => setEmail(e.target.value)} required />
      <input type="password" value={password} onChange={e => setPassword(e.target.value)} required />
      <button type="submit" disabled={busy}>{busy ? 'Signing in…' : 'Sign in'}</button>
    </form>
  );
}

A devices list (auto-refreshes every 30s)

// src/components/DevicesList.tsx
import { useEffect, useState } from 'react';
import { sensrik } from '../lib/sensrik';
import type { Device } from '../lib/sensrik.js';

export function DevicesList() {
  const [devices, setDevices] = useState<Device[]>([]);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    let cancelled = false;
    async function load() {
      try {
        const list = await sensrik.devices.list();
        if (!cancelled) {
          setDevices(list);
          setError(null);
        }
      } catch (err: any) {
        if (!cancelled) setError(err?.message ?? 'Failed to load');
      } finally {
        if (!cancelled) setLoading(false);
      }
    }
    load();
    const interval = setInterval(load, 30_000);
    return () => { cancelled = true; clearInterval(interval); };
  }, []);

  if (loading) return <p>Loading…</p>;
  if (error) return <p style={{ color: 'red' }}>{error}</p>;
  if (devices.length === 0) return <p>No devices yet.</p>;

  return (
    <ul>
      {devices.map(d => (
        <li key={d.id}>
          <strong>{d.name}</strong> — {d.isOnline ? '🟢 online' : '⚪ offline'} — {d.batterySoc ?? '—'}%
        </li>
      ))}
    </ul>
  );
}

For a full storefront — login + devices + device detail with live charts — ask your Sensrik admin for the vanilla template and reimplement the pages in React. The SDK calls are the same.