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.