Reputation: 46479
I am trying to programatically focus TextInput
element with a certain delay after it has mounted, I've got following component (a view that shows input and button)
For some reason this gets error saying
_this2.inputRef.focus is not a function
I'm not sure why. One out of place thing is that I get flow saying that createRef()
doesn't exist on React
, but I am assuming this is just missing flow definition now, as I am using react 16.3.1
and this was added in 16.3, plus there is no error when its called.
// @flow
import React, { Component, Fragment } from 'react'
import Button from '../../composites/Button'
import TextInput from '../../composites/TextInput'
import OnboardingStore from '../../store/OnboardingStore'
import withStore from '../../store'
import { durationNormal } from '../../services/Animation'
/**
* Types
*/
export type Props = {
OnboardingStore: OnboardingStore
}
/**
* Component
*/
class CharacterNameView extends Component<Props> {
componentDidMount() {
this.keyboardTimeout = setTimeout(() => this.inputRef.focus(), durationNormal)
}
componentWillUnmount() {
clearTimeout(this.keyboardTimeout)
}
keyboardTimeout: TimeoutID
inputRef = React.createRef()
render() {
const { OnboardingStore } = this.props
return (
<Fragment>
<TextInput
ref={this.inputRef}
enablesReturnKeyAutomatically
value={OnboardingStore.state.username}
onChangeText={username => OnboardingStore.mutationUsername(username)}
placeholder="Username"
blurOnSubmit
returnKeyType="done"
onSubmitEditing={/* TODO */ () => null}
/>
<Button disabled={!OnboardingStore.state.username} color="GREEN" onPress={() => null}>
Create
</Button>
</Fragment>
)
}
}
export default withStore(OnboardingStore)(CharacterNameView)
TextInput component I use is imported from this file
// @flow
import React, { Component } from 'react'
import { StyleSheet, TextInput as Input } from 'react-native'
import RatioBgImage from '../components/RatioBgImage'
import { deviceWidth } from '../services/Device'
/**
* Types
*/
export type Props = {
style?: any
}
/**
* Component
*/
class TextInput extends Component<Props> {
static defaultProps = {
style: null
}
render() {
const { style, ...props } = this.props
return (
<RatioBgImage source={{ uri: 'input_background' }} width={70} ratio={0.1659}>
<Input
{...props}
placeholderTextColor="#4f4a38"
selectionColor="#797155"
autoCapitalize="none"
autoCorrect={false}
keyboardAppearance="dark"
style={[styles.input, style]}
/>
</RatioBgImage>
)
}
}
export default TextInput
/**
* Styles
*/
const styles = StyleSheet.create({
input: {
width: '96.4%',
height: '97.45%',
color: '#797155',
fontSize: deviceWidth * 0.043,
marginLeft: '1%',
paddingLeft: '5%'
}
})
Below is what this.innerRef
looks like, I don't see any focus property on it at the moment
Upvotes: 2
Views: 4802
Reputation: 46479
My issue was in using React.createRef()
and assuming I am setting it on a child component. Unfortunately I missed part of the docs about React.forwardRef That I had to use in a child component so ref gets set properly.
Upvotes: 0
Reputation: 4260
inputRef
is a property of the class instance, set it inside a class method.
Using a constructor, for instance:
class CharacterNameView extends Component<Props> {
constructor() {
this.inputRef = React.createRef()
}
...
}
Upvotes: 1