【问题标题】:Proper ref handling with react-simple-keyboard使用 react-simple-keyboard 正确处理 ref
【发布时间】:2020-02-06 18:26:29
【问题描述】:

我正在使用react-simple-keyboard,并通过使用空字符串调用useState 钩子的设置器来清除我的输入会清除输入,但不会清除键盘的“内存”,因此下次您键入时,您将添加到再次使用旧字符串。

react-simple-keyboard (RSK) 有一个 clearInput 函数可以解决问题,并且(据我了解)它必须在 keyboardRef 上调用。所以我把它装了起来:

我的键盘组件(包装器)

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>
  );
};

这可行,但有代码味道:我正在消费组件中创建 ref(然后我将它传递给我的键盘包装器,以便 RSK 可以使用它,我可以在上面调用 clearInput) ,并在消费组件中使用 RSK 方法而不是键盘包装器。

使用键盘的组件应该使用并知道 RSK 的 ref 似乎是错误的。这也意味着消费组件中keyboard.current! 的类型是never(或其他一些无法管理的类型),所以我使用@ts-ignore 作为创可贴。

解决这个问题的正确正确方法是什么?

更新:我尝试了suggested solution,但它不起作用。我真正做的唯一改变是我没有在内部组件(KeyboardElement)中使用传递的ref,我在KeyboardElement上定义了一个clearInput函数,它只调用its ref 的 clearInput 函数。但是消费组件中的 ref 始终是undefined

我认为我的情况和另一种情况的区别在于我不是在调用 ref 的函数,而是在调用“嵌套 ref”的函数。我将父母的 ref 作为道具传递给孩子,以便孩子可以将 its ref 分配给该道具,这似乎是错误的。

【问题讨论】:

  • 读完这篇文章,你会非常生动地理解这个想法stackoverflow.com/questions/43266582/…
  • 谢谢,但这对我来说不太有效。查看我的更新。
  • 您可以通过将 hooks 值设置为 '' " 或使用 Ref 来清除值。做其中之一,而不是两者。我更喜欢你只清除 hook 值。没有打字稿或在那里输入错误。
  • 清除 hooks 值确实会清除 my 组件的文本。但是react-simple-keyboard 正在存储它的 自己的 状态来跟踪已按下的键,这意味着在清除挂钩值后下次键入时,您仍然拥有之前按下的键。我能找到清除键盘自身状态的唯一方法是使用它的clearInput 方法。我确实在链接的帖子中尝试了“使用密钥”策略,但这也不起作用。
  • 谢谢@FranciscoHodge。我实际上采取了另一种策略——我没有使用清除按钮来调用嵌套的keyboard.clearInput,而是将键盘用作更真正受控的组件,其中我的simple-keyboard 的更改处理程序将键入的字符传递给其父处理程序然后clearInput 清除了键盘的缓冲区,这样键盘一次只能处理一个字符。

标签: reactjs typescript react-simple-keyboard


【解决方案1】:

我使用 3.1.9 版本的方法是同时导入 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}
/>

【讨论】:

    猜你喜欢
    • 2018-01-15
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 2014-02-03
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 2019-10-16
    相关资源
    最近更新 更多