My React/Motoko notes app shows a Signature Verification Error

Hi! Your signature verification error on reload is a classic symptom of outdated ICP frontend patterns (old agent + manual identity/rootKey handling). The old setup often fails to restore the authenticated identity on full refresh, leading to anonymous calls that the canister rejects.

Highly recommend switching to @ic-reactor/react (v3) — it’s built on the latest ICP SDK/agent, fully compatible with current dfx/ICP updates, heavily tested in production-like demos (e.g. ckBTC/ICRC wallets), and solves exactly these auth/reload + boilerplate issues with TanStack Query under the hood.

It’s in beta but the core is stable, actively maintained (recent Jan 2026 updates), and many devs are adopting it for cleaner, more reliable React + Motoko apps.

Quick Install (use beta for latest)

npm install @ic-reactor/react@beta @icp-sdk/core @tanstack/react-query

Super Simple Notes App Example (Tailored to Your Case)

Assume your Motoko backend actor looks like this (common tutorial style):

actor Notes {
  stable var notes : [Text] = [];

  public query func getNotes() : async [Text] { notes };

  public func addNote(note : Text) : async () {
    notes := Array.append(notes, [note]);
  };
}
  1. Setup reactor (put in src/lib/reactor.ts or similar):
import { ClientManager, Reactor } from "@ic-reactor/react";
import { QueryClient } from "@tanstack/react-query";
import { idlFactory, type _SERVICE } from "../declarations/notes"; // from dfx generate

const queryClient = new QueryClient(); // optional: add devtools later

export const clientManager = new ClientManager({ queryClient });

export const notesActor = new Reactor<_SERVICE>({
  clientManager,
  idlFactory,
  canisterId: process.env.CANISTER_ID_NOTES ?? "your-local-canister-id-here",
  name: "notes",
});
  1. Create hooks (src/hooks/useNotes.ts):
import { createActorHooks } from "@ic-reactor/react";
import { notesActor } from "../lib/reactor";

export const { useActorQuery, useActorMutation } = createActorHooks(notesActor);
  1. Your React component (replaces your broken useEffect fetch):
// App.tsx or Notes.tsx
import { useActorQuery, useActorMutation } from "./hooks/useNotes";
import { useState } from "react";

function NotesApp() {
  const [newNote, setNewNote] = useState("");

  // Auto-fetches on mount + reload — no useEffect, no signature errors!
  const { data: notes = [], isPending, error } = useActorQuery({
    functionName: "getNotes",
  });

  const addMutation = useActorMutation({
    functionName: "addNote",
    onSuccess: () => {
      // Auto-refresh the notes list after adding
      queryClient.invalidateQueries({
        queryKey: notesActor.generateQueryKey({ functionName: "getNotes" }),
      });
    },
  });

  const handleAdd = () => {
    if (newNote.trim()) {
      addMutation.mutate([newNote]); // args as array
      setNewNote("");
    }
  };

  if (isPending) return <p>Loading your notes...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <div>
      <h1>My ICP Notes</h1>
      <ul>
        {notes.map((note, index) => (
          <li key={index}>{note}</li>
        ))}
      </ul>

      <input
        value={newNote}
        onChange={(e) => setNewNote(e.target.value)}
        placeholder="Add a new note..."
      />
      <button onClick={handleAdd} disabled={addMutation.isPending}>
        {addMutation.isPending ? "Adding..." : "Add Note"}
      </button>
    </div>
  );
}

export default NotesApp;

Wrap your root app with the provider (in main.tsx or index.tsx):

import { QueryClientProvider } from "@tanstack/react-query";
import { queryClient } from "./lib/reactor"; // or create inline

<QueryClientProvider client={queryClient}>
  <NotesApp />
</QueryClientProvider>

Now:

  • Notes load automatically on page reload (auth persists via Internet Identity).
  • Adding a note instantly refreshes the list.
  • No manual agent, identity login boilerplate, or rootKey fixes needed.

If you need explicit login/logout buttons, check the docs for createAuthHooks.

Docs: Overview | IC Reactor
Beta announcement & more demos: [v3 Beta Announcement] IC Reactor: The "Missing" Data-Fetching Library for Internet Computer

Try this — it should make your app feel modern and reliable. If you get any setup errors (e.g. with declarations or canister ID), share them and I’ll help debug! :rocket: