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')
  const [message, setMessage] = React.useState('')

  const handleSuccess = (token) => {
    // Always accesses current userType value
    setMessage(`${userType} login successful!`)
    submitForm(token, userType)
  }

  return (
    <form>
      <select value={userType} onChange={(e) => setUserType(e.target.value)}>
        <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')
  const [message, setMessage] = React.useState('')

  const userCallback = useCallback((token) => {
    setMessage('User login successful!')
    submitUserForm(token)
  }, [])

  const adminCallback = useCallback((token) => {
    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)}>
        <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.