Skip to content

Commit

Permalink
flow: Use typeof TextInput when we want the type, not the value.
Browse files Browse the repository at this point in the history
We add `typeof` in several places to address this Flow error that
starts appearing at the RN and Flow upgrade:

```
Cannot use `TextInput` as a type. A name can be used as a type only
if it refers to a type definition, an interface definition, or a
class definition. To get the type of a non-class value, use
`typeof`.
```

I'm not sure if this is due to the Flow upgrade or to changes React
Native made to `TextInput`, or both. Several changes to `TextInput`
are announced in the RN changelog [1], including three that are
breaking, but I haven't been able to identify any in particular that
would start giving us that error.

With that dealt with, we also get this new error on calling various
methods on the instance stored at a `TextInput` ref (e.g.,
`textInputRef.current.focus()`):

```
Cannot call textInputRef.current.focus because:
 • Either property focus is missing in AbstractComponent [1].
 • Or property focus is missing in object type [2].
```

At first, I thought something was wrong with how we're annotating
the variable storing the ref, or that Flow didn't fully understand
the `React.createRef` API (we started using that in a recent commit
before the main upgrade commit). But rather, it seems to be an issue
that's known to occur at RN v0.61.1, and which didn't occur on
`master` as of 2020-04-06 [2]. Checking commits around that date in
`react-native`, I'm pretty sure we'll have a fix in RN v0.63
(zulip#4245).

[1] https://github.com/react-native-community/releases/blob/master/CHANGELOG.md#0620
[2] See point 2 at
    facebook/react-native#28459 (comment).
  • Loading branch information
chrisbobbe committed Sep 11, 2020
1 parent cd501a7 commit 0aa8135
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 21 deletions.
6 changes: 3 additions & 3 deletions src/common/Input.js
Expand Up @@ -8,10 +8,10 @@ import type { ThemeData } from '../styles';
import { ThemeContext, HALF_COLOR, BORDER_COLOR } from '../styles';

export type Props = $ReadOnly<{|
// TextInput's definition changes across the RN v0.61 -> v0.62
// upgrade; we'll handle that change after the upgrade.
// See point 2 at
// https://github.com/facebook/react-native/issues/28459#issuecomment-609957836
// $FlowFixMe
...$PropertyType<TextInput, 'props'>,
...$PropertyType<typeof TextInput, 'props'>,
placeholder: LocalizableText,
onChangeText?: (text: string) => void,
textInputRef?: React$Ref<typeof TextInput>,
Expand Down
8 changes: 4 additions & 4 deletions src/common/InputWithClearButton.js
Expand Up @@ -32,10 +32,7 @@ export default class InputWithClearButton extends PureComponent<Props, State> {
canBeCleared: false,
text: '',
};
// TextInput's definition changes across the RN v0.61 -> v0.62
// upgrade; we'll handle that change after the upgrade.
// $FlowFixMe
textInputRef = React.createRef<TextInput>();
textInputRef = React.createRef<typeof TextInput>();

handleChangeText = (text: string) => {
this.setState({
Expand All @@ -50,6 +47,9 @@ export default class InputWithClearButton extends PureComponent<Props, State> {
handleClear = () => {
this.handleChangeText('');
if (this.textInputRef.current) {
// See point 2 at
// https://github.com/facebook/react-native/issues/28459#issuecomment-609957836
// $FlowFixMe
this.textInputRef.current.clear();
}
};
Expand Down
12 changes: 8 additions & 4 deletions src/common/SmartUrlInput.js
Expand Up @@ -66,15 +66,15 @@ export default class SmartUrlInput extends PureComponent<Props, State> {
state = {
value: '',
};
// TextInput's definition changes across the RN v0.61 -> v0.62
// upgrade; we'll handle that change after the upgrade.
// $FlowFixMe
textInputRef = React.createRef<TextInput>();
textInputRef = React.createRef<typeof TextInput>();
focusListener: void | NavigationEventSubscription;

componentDidMount() {
this.focusListener = this.props.navigation.addListener('didFocus', () => {
if (this.textInputRef.current) {
// See point 2 at
// https://github.com/facebook/react-native/issues/28459#issuecomment-609957836
// $FlowFixMe
this.textInputRef.current.focus();
}
});
Expand All @@ -96,9 +96,13 @@ export default class SmartUrlInput extends PureComponent<Props, State> {
urlPress = () => {
const { textInputRef } = this;
if (textInputRef.current) {
// See point 2 at
// https://github.com/facebook/react-native/issues/28459#issuecomment-609957836
// $FlowFixMe
textInputRef.current.blur();
setTimeout(() => {
if (textInputRef.current) {
// $FlowFixMe - same as above
textInputRef.current.focus();
}
}, 100);
Expand Down
22 changes: 12 additions & 10 deletions src/compose/ComposeBox.js
Expand Up @@ -105,16 +105,16 @@ function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

// TextInput's definition changes across the RN v0.61 -> v0.62
// upgrade; we'll handle that change after the upgrade.
// $FlowFixMe
export const updateTextInput = (textInput: TextInput | null, text: string): void => {
export const updateTextInput = (textInput: typeof TextInput | null, text: string): void => {
if (textInput === null) {
// Depending on the lifecycle events this function is called from,
// this might not be set yet.
return;
}

// See point 2 at
// https://github.com/facebook/react-native/issues/28459#issuecomment-609957836
// $FlowFixMe
textInput.setNativeProps({ text });

if (text.length === 0 && TextInputReset) {
Expand All @@ -128,12 +128,8 @@ class ComposeBox extends PureComponent<Props, State> {
static contextType = ThemeContext;
context: ThemeData;

// TextInput's definition changes across the RN v0.61 -> v0.62
// upgrade; we'll remove these fixmes after we take that upgrade.
// $FlowFixMe
messageInputRef = React.createRef<TextInput>();
// $FlowFixMe
topicInputRef = React.createRef<TextInput>();
messageInputRef = React.createRef<typeof TextInput>();
topicInputRef = React.createRef<typeof TextInput>();

// TODO: Type-check this, once we've adjusted our `react-redux`
// wrapper to do the right thing. It should be
Expand Down Expand Up @@ -344,6 +340,9 @@ class ComposeBox extends PureComponent<Props, State> {
}
completeEditMessage();
if (this.messageInputRef.current !== null) {
// See point 2 at
// https://github.com/facebook/react-native/issues/28459#issuecomment-609957836
// $FlowFixMe
this.messageInputRef.current.blur();
}
};
Expand All @@ -358,6 +357,9 @@ class ComposeBox extends PureComponent<Props, State> {
this.setMessageInputValue(message);
this.setTopicInputValue(topic);
if (this.messageInputRef.current !== null) {
// See point 2 at
// https://github.com/facebook/react-native/issues/28459#issuecomment-609957836
// $FlowFixMe
this.messageInputRef.current.focus();
}
}
Expand Down

0 comments on commit 0aa8135

Please sign in to comment.