Skip to content

Commit

Permalink
flow fixes (handle properly TODO): TextInput
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 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 2, 2020
1 parent 04c19e5 commit d2f0e00
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 6 deletions.
5 changes: 4 additions & 1 deletion src/common/Input.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import type { ThemeData } from '../styles';
import { ThemeContext, HALF_COLOR, BORDER_COLOR } from '../styles';

export type Props = $ReadOnly<{|
...$PropertyType<TextInput, 'props'>,
// See point 2 at
// https://github.com/facebook/react-native/issues/28459#issuecomment-609957836
// $FlowFixMe
...$PropertyType<typeof TextInput, 'props'>,
placeholder: LocalizableText,
onChangeText?: (text: string) => void,
textInputRef?: React$Ref<typeof TextInput>,
Expand Down
5 changes: 4 additions & 1 deletion src/common/InputWithClearButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default class InputWithClearButton extends PureComponent<Props, State> {
canBeCleared: false,
text: '',
};
textInputRef = React.createRef<TextInput>();
textInputRef = React.createRef<typeof TextInput>();

handleChangeText = (text: string) => {
this.setState({
Expand All @@ -47,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
9 changes: 8 additions & 1 deletion src/common/SmartUrlInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,15 @@ export default class SmartUrlInput extends PureComponent<Props, State> {
state = {
value: '',
};
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 @@ -93,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
15 changes: 12 additions & 3 deletions src/compose/ComposeBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,16 @@ function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

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 @@ -125,8 +128,8 @@ class ComposeBox extends PureComponent<Props, State> {
static contextType = ThemeContext;
context: ThemeData;

messageInputRef = React.createRef<TextInput>();
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 @@ -341,6 +344,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 @@ -355,6 +361,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 d2f0e00

Please sign in to comment.