Fix useMemo returns new component on change (#2315)

This fixes setting the input value on scan if the component remounts while the scanner is open.

No need to use useRef to close the scanner on remount.
This commit is contained in:
ekzyis 2025-07-23 18:50:39 +02:00 committed by GitHub
parent 243b094fcd
commit 3f74279f29
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 35 additions and 46 deletions

View File

@ -1350,21 +1350,11 @@ function PasswordScanner ({ onScan, text }) {
loading: () => <PageLoading /> loading: () => <PageLoading />
}) })
const closeRef = useRef()
useEffect(() => {
return () => {
// close modal on remount to avoid calling stale callbacks
// see https://github.com/stackernews/stacker.news/pull/2313
closeRef.current?.()
}
}, [])
return ( return (
<InputGroup.Text <InputGroup.Text
style={{ cursor: 'pointer' }} style={{ cursor: 'pointer' }}
onClick={() => { onClick={() => {
showModal(onClose => { showModal(onClose => {
closeRef.current = onClose
return ( return (
<div> <div>
{text && <h5 className='line-height-md mb-4 text-center'>{text}</h5>} {text && <h5 className='line-height-md mb-4 text-center'>{text}</h5>}

View File

@ -49,7 +49,7 @@ export default function Wallet () {
? ( ? (
<WalletLayout> <WalletLayout>
<div className='py-5 d-flex flex-column align-items-center justify-content-center flex-grow-1 mx-auto' style={{ maxWidth: '500px' }}> <div className='py-5 d-flex flex-column align-items-center justify-content-center flex-grow-1 mx-auto' style={{ maxWidth: '500px' }}>
<PassphrasePrompt /> {PassphrasePrompt}
</div> </div>
</WalletLayout> </WalletLayout>
) )

View File

@ -238,42 +238,41 @@ export function usePassphrasePrompt () {
const [showPassphrasePrompt, setShowPassphrasePrompt] = useState(false) const [showPassphrasePrompt, setShowPassphrasePrompt] = useState(false)
const togglePassphrasePrompt = useCallback(() => setShowPassphrasePrompt(v => !v), []) const togglePassphrasePrompt = useCallback(() => setShowPassphrasePrompt(v => !v), [])
const Prompt = useMemo(() => const Prompt = useMemo(() => (
() => ( <div>
<div> <h4>Wallet decryption</h4>
<h4>Wallet decryption</h4> <p className='line-height-md mt-3'>
<p className='line-height-md mt-3'> Your wallets have been encrypted on another device. Enter your passphrase to use your wallets on this device.
Your wallets have been encrypted on another device. Enter your passphrase to use your wallets on this device. </p>
</p> <p className='line-height-md'>
<p className='line-height-md'> {showPassphrase && 'You can find the button to reveal your passphrase above your wallets on the other device.'}
{showPassphrase && 'You can find the button to reveal your passphrase above your wallets on the other device.'} </p>
</p> <p className='line-height-md'>
<p className='line-height-md'> Press reset if you lost your passphrase.
Press reset if you lost your passphrase. </p>
</p> <Form
<Form schema={passphraseSchema({ hash, salt })}
schema={passphraseSchema({ hash, salt })} initial={{ passphrase: '' }}
initial={{ passphrase: '' }} onSubmit={onSubmit}
onSubmit={onSubmit} >
> <PasswordInput
<PasswordInput label='passphrase'
label='passphrase' name='passphrase'
name='passphrase' placeholder=''
placeholder='' required
required autoFocus
autoFocus qr
qr />
/> <div className='mt-3'>
<div className='mt-3'> <div className='d-flex justify-content-between align-items-center'>
<div className='d-flex justify-content-between align-items-center'> <Button className='me-auto' variant='danger' onClick={resetPassphrase}>reset</Button>
<Button className='me-auto' variant='danger' onClick={resetPassphrase}>reset</Button> <Button className='me-3 text-muted nav-link fw-bold' variant='link' onClick={togglePassphrasePrompt}>cancel</Button>
<Button className='me-3 text-muted nav-link fw-bold' variant='link' onClick={togglePassphrasePrompt}>cancel</Button> <SubmitButton variant='primary'>save</SubmitButton>
<SubmitButton variant='primary'>save</SubmitButton>
</div>
</div> </div>
</Form> </div>
</div> </Form>
), [showPassphrase, resetPassphrase, togglePassphrasePrompt, onSubmit, hash, salt]) </div>
), [showPassphrase, resetPassphrase, togglePassphrasePrompt, onSubmit, hash, salt])
return useMemo( return useMemo(
() => [showPassphrasePrompt, togglePassphrasePrompt, Prompt], () => [showPassphrasePrompt, togglePassphrasePrompt, Prompt],