Reputation: 13278
I am using react-simple-keyboard
, and clearing my input by calling the useState
hook's setter with an empty string clears the input but doesn't clear the keyboard's "memory", so the next time you type you are adding to the old string again.
react-simple-keyboard
(RSK) has a clearInput
function that does the trick, and (as I understand it) it has to be called on the keyboardRef
. So I rigged that up:
export default KeyboardElement = ({ onChange, keyboardRef }) => {
return <KeyboardContainer>
<Keyboard
layout={ {
'default': [
'1 2 3 4 5 6 7 8 9 0',
'Q W E R T Y U I O P',
'A S D F G H J K L',
'Z X C V B N M {bksp}',
],
} }
theme={ 'firmm-keyboard' }
keyboardRef={ keyboardRef }
onChange={ onChange }
/>
</KeyboardContainer>;
};
export default LicenseEntry = ({ onClose }) => {
const [text, setText] = useState('');
const keyboard = useRef();
const onClear = () => {
// @ts-ignore
keyboard.current!.clearInput();
setText('');
};
return (
<FullScreenModalBackground zIndex={ 9 }>
<OuterContainer>
<InnerContainer>
<ExitButton onClose={ onClose }/>
<HeaderText>Add license</HeaderText>
<Input
readOnly
data-testid="LICENSE_INPUT"
value={ formatLicense(text) }
placeholder={ 'type license here' }
/>
<KeyboardElement
keyboardRef={ r => keyboard.current = r }
onChange={ setText }
/>
<Button>Submit</Button>
<Button onClick={ onClear }>Clear</Button>
</InnerContainer>
</OuterContainer>
</FullScreenModalBackground>
);
};
This works, but has a code smell: I'm creating the ref in the consuming component (I'm then passing it to my keyboard wrapper so that RSK can use it, and I can call clearInput
on it), and using the RSK method in the consuming component instead of the keyboard wrapper.
It seems wrong that the component using the keyboard should be using and knowing about the RSK's ref. It also means that the type of keyboard.current!
in the consuming component is never
(or some other unmanageable type) and so I'm using the @ts-ignore
as a band aid.
What is the proper correct way to go about this?
Update: I've tried the suggested solution but it's not working. The only change I actually make is that I don't used the passed ref
in the inner component (KeyboardElement
) and I define a clearInput
function on KeyboardElement
which just calls its ref's clearInput
function. But the ref in the consuming component is always undefined
.
I think the difference between my situation and the other one is that I'm not calling a function of the ref, I'm calling the function of the "nested ref". I'm passing the parent's ref to the child as a prop so that the child can assign its ref to that prop, and that seems wrong.
Upvotes: 6
Views: 3822
Reputation: 101
the way i got this working with version 3.1.9 was to also import KeyboardReactInterface
import Keyboard, { KeyboardReactInterface } from 'react-simple-keyboard'
const keyboardRef = useRef<KeyboardReactInterface | null>(null)
<Keyboard
keyboardRef={(r) => (keyboardRef.current = r)}
onChange={onChange}
onKeyPress={onKeyPress}
layoutName={layoutName}
/>
Upvotes: 5