Given the sample code
<InputGroup>
<Icon name="ios-home" />
<Input
ref={() => (console.log("onref"))}
/>
</InputGroup>
the ref callback is never called (most likely due to cloning logic in InputGroup.
Additionally my guess is that I would be unable to call native focus method as it works for normal RN TextInput
Yes, I am also having this issue. I am unable to call focus on an InputGroup Input with a ref.
Okay, thanks for bringing it to our attention. We'll look into it.
I have my version of a fix with these two pull requests:
Using React.cloneElement instead allows maintaining of the ref assigned to an Input (object references and string references both work using this patch)
Add a ref directly to the native TextInput. This allows you in your code to do something like this:
focusPasswordInput() {
this._passwordInput._textInput.focus();
}
render() {
return (
<Container>
<Content>
<InputGroup style={{marginBottom: 20}}>
<Icon name="ios-person" />
<Input
ref={c => this._usernameInput = c}
autoCapitalize="none"
autoCorrect={false}
placeholder="USERNAME"
onChangeText={(username) => this.setState({username})}
onSubmitEditing={() => this.focusPasswordInput()}
returnKeyType="next"
value={this.state.username}
/>
</InputGroup>
<InputGroup style={{marginBottom: 10}}>
<Icon name="ios-unlock-outline" />
<Input
ref={c => this._passwordInput = c}
placeholder="PASSWORD"
secureTextEntry={true}
onChangeText={(password) => this.setState({password})}
returnKeyType="go"
value={this.state.password}
/>
</InputGroup>
</Content>
</Container>
)
}
Fixed in 0.5.5 Thanks @pwoltman !
I'm in version 0.5.9 and a call to focus brings the "is not a function" error.
I'm setting a simple string ref (like "password") and calling "onSubmitEditing={() => this.refs.password.focus()}.
And getting a weird "_this2.refs.password.focus is not a function" error.
Perfect! Thank you!
why I can't use _textInput because undefined but I change like this it work.
change _textInput to _root
focusPasswordInput() {
this._passwordInput._root.focus();
}
@oneatcoe What version of NativeBase are you running? Can you post the portion of your code where you are creating the main Input component and trying to reference the child TextInput?
In version 2.0.10 the ref property of Input is ignored if the Item has label is a floatingLabel or a stackedLabel.
Same problem here on 2.0.11
This working code are using this package.json:
"dependencies": {
"native-base": "^2.0.12",
"react": "~15.4.1",
"react-native": "0.42.0",
"react-native-responsive-image": "^2.0.2"
},
<Form style={{marginTop:20}}>
<Item>
<Icon active name='ios-at-outline' />
<Input
ref='email'
placeholder='your email'
keyboardType='email-address'
returnKeyType='next'
autoCapitalize='none'
onSubmitEditing={()=>{this.refs.passwordField._root.focus();}}
/>
</Item>
<Item last>
<Icon active name='ios-finger-print-outline' />
<Input
ref='passwordField'
placeholder='your password'
returnKeyType='go'
secureTextEntry
autoCapitalize='none'
/>
</Item>
</Form>
@makeitnew @egiordano and others with the same problem using Item as floatingLabel.
After digging for a while the Item.js source code I ended up with this solution (I am using nativebase 2.0.12).
class Screen extends Component {
(...)
componentDidMount() {
this.textInput._root.focus();
this.textInput.props.onChangeText(this.props.inputValue);
}
(...)
<Item floatingLabel>
<Label>SomeLabel</Label>
<Input
getRef={(input) => { this.textInput = input; }}
keyboardType="numeric"
onChangeText={text => this.setState({ inputValue: text })}
value={this.state.inputValue}
/>
</Item>
(...)
}
this.textInput.props.onChangeText(this.props.inputValue); is only needed if one wants to load the Input with a initial value.
@franciscocpg - That finally worked! I have not found any reference to 'getRef' in the documentation and that should be fixed - this method seems to work the best.
More generic solution:
```export default class SignUpForm extends Component {
_focusInput(inputField) {
this[inputField]._root.focus();
}
render() {
return (
keyboardType='numeric'
returnKeyType='next'
getRef={(input) => this.mobileInput = input}
onSubmitEditing={() => this._focusInput('passwordInput')}
/>
secureTextEntry={true}
returnKeyType='next'
getRef={(input) => this.passwordInput = input}
onSubmitEditing={() => this._focusInput('emailInput')}
/>
...........
My solution is create Wrapper to style input inside. Keep input as native as posible.
const Wrapper = styled.div`
width: 100%
input {
background-color: red;
}
`;
class SearchInput extends React.Component {
setFocus = () => {
this.textInput.focus();
}
render() {
return (
<Wrapper>
<button onClick={this.setFocus}>focus input</button>
<input ref={el => { this.textInput = el; }} />
</Wrapper>
);
}
}
So, using typescript with this reveals that this is a design flaw. _root doesn't exist on type Input. so typecsript won't let me access the focus() method
To avoid flow validating errors just use the following:
this.textInputRef && this.textInputRef._root.focus();
I have a similar need because
I want to give a focus in the <Input ... getRef={(input) => { this.textInput = input; }} after a click on the <Button>, but whenever I bind to a function and call a reference, for example:
setFocusInput(){
this.textInput._root.focus();
}
return TypeError: undefined is not an object (evaluating 'this.textInput._root')
Someone could help with this situation?
Check Docs
Most helpful comment
@makeitnew @egiordano and others with the same problem using
ItemasfloatingLabel.After digging for a while the
Item.jssource code I ended up with this solution (I am using nativebase 2.0.12).this.textInput.props.onChangeText(this.props.inputValue);is only needed if one wants to load theInputwith a initial value.