Dynamic Callbacks
By default, callbacks always access the latest state/props without re-rendering the widget. For cases where you need the widget to re-render when callbacks change, use rerenderOnCallbackChange={true}.
Default Behavior
import { Turnstile } from "@marsidev/react-turnstile";
export default function LoginForm() {
const [userType, setUserType] = React.useState<"user" | "admin">("user");
const [message, setMessage] = React.useState("");
const handleSuccess = (token: string) => {
// Always accesses current userType value
setMessage(`${userType} login successful!`);
submitForm(token, userType);
};
return (
<form>
<select value={userType} onChange={(e) => setUserType(e.target.value as "user" | "admin")}>
<option value="user">User</option>
<option value="admin">Admin</option>
</select>
<input type="email" placeholder="Email" />
<input type="password" placeholder="Password" />
<Turnstile siteKey="1x00000000000000000000AA" onSuccess={handleSuccess} />
<button type="submit">Login as {userType}</button>
{message && <p>{message}</p>}
</form>
);
}
Dynamic Callbacks with Re-rendering
import { Turnstile } from "@marsidev/react-turnstile";
import { useCallback } from "react";
export default function LoginForm() {
const [userType, setUserType] = React.useState<"user" | "admin">("user");
const [message, setMessage] = React.useState("");
const userCallback = useCallback((token: string) => {
setMessage("User login successful!");
submitUserForm(token);
}, []);
const adminCallback = useCallback((token: string) => {
setMessage("Admin login successful!");
submitAdminForm(token); // Different submission logic
}, []);
const currentCallback = userType === "user" ? userCallback : adminCallback;
return (
<form>
<select value={userType} onChange={(e) => setUserType(e.target.value as "user" | "admin")}>
<option value="user">User</option>
<option value="admin">Admin</option>
</select>
<input type="email" placeholder="Email" />
<input type="password" placeholder="Password" />
<Turnstile
siteKey="1x00000000000000000000AA"
rerenderOnCallbackChange={true}
onSuccess={currentCallback}
/>
<button type="submit">Login as {userType}</button>
{message && <p>{message}</p>}
</form>
);
}
When using rerenderOnCallbackChange={true}, always wrap your callback functions with useCallback to prevent unnecessary widget re-renders.