I am using a state to store the text and update it as typed. The value of the TextInput is then changed as the state is changed. This works as a packaged app but not in a an ios browser. Please let me know if there is a better way to implement this or make it work. Thank you.
const function1 = (props) => {
const [text, setText] = useState("");
return (
<View>
<TextInput
style={styles.textInput}
onChangeText={(t) => setText(t)}
placeholder="placeholder..."
value={text}
autoCorrect={false}
autoCapitalize="words"
onSubmitEditing={() => {
doSomething(text);
setText("");
}}
/>
<View/>
);
};
I have a functional component in which I am trying to clear a TextInput on submit. Sometimes the onChangeText callback is called after onSubmitEditing, so the input is not clear after submitting. Most often this happens due to autocorrect, but sometimes happens with random strings that were not autocorrected. How do I make sure the input is cleared consistently?
Code: https://snack.expo.io/hy4dKvvnr
export default function App() {
const [inputValue, setInputValue] = useState('');
return (
<View style={styles.container}>
<TextInput
style={styles.input}
value={inputValue}
onChangeText={(value) => {
console.log('CHANGE TEXT', value);
setInputValue(value);
}}
blurOnSubmit
onSubmitEditing={() => {
console.log('SUBMIT TEXT');
setInputValue('');
}}
/>
</View>
);
}
Console logs:
iPhone 8: CHANGE TEXT Kdjgw
iPhone 8: SUBMIT TEXT
iPhone 8: CHANGE TEXT Kdjgw
I have this simple code of a TextInput that I want it to get focus when it first renders and on submits. However, it does not get focus at all.
render() {
return (
<TextInput
ref={(c) => this._input = c}
style={[styles.item, this.props.style]}
placeholder={"New Skill"}
onChangeText={(text) => {
this.setState({text})
}}
onSubmitEditing={(event) => {
this.props.onSubmitEditing(this.state.text);
this._input.clear();
this._input.focus();
}}
/>
);
}
componentDidMount() {
this._input.focus();
}
So my assumption is true. Try to focus is failed, this._input doesn't contain anything when componentDidMount called, because render function still not called yet and no reference for it.
So the solution for now is delay it a little bit until render function already called.
Thats why wrap the code inside setTimeout function quite helpful. Anyway i admit it, it is a little bit tricky. Would be great if someone find the better way.
componentDidMount() {
setTimeout(() => this._input.focus(), 250);
}
You can use autoFocus property of TextInput and set it to true. It will focus TextInput on componentDidMount automatically.I tested it and it's focusing input on both componentDidMount and onSubmitEditing.
render() {
return (
<TextInput
ref={(c) => this._input = c}
placeholder={"New Skill"}
autoFocus={true}
onChangeText={(text) => {
this.setState({text})
}}
onSubmitEditing={() => {
this.props.onSubmitEditing(this.state.text);
this._input.clear();
this._input.focus();
}}
/>
);
}
I'm using React Native's TextInput. I want to disable return key as per the requirement. Is there any way to disable/enable return key by custom code?
I tried with enablesReturnKeyAutomatically but it doesn't work.
Yes we can, by using the onSubmitEditing props for TextInput. Posting sample here:
<TextInput
value={password}
returnKeyType="done"
onSubmitEditing={() => {
if (password != '') {
onLoginPressed();
}
}}
placeholder="Password"
sub_place="PASSWORD"
onChangeText={value => setPassword(value)}
blurOnSubmit={false}
ref={passwordFocus}
/>
Is there a way to programmatically highlight/select text that is inside a TextInput component?
You can use selectTextOnFocus to achieve this. This will ensure that all text inside the TextInput is highlighted when the field is tapped into.
Actually you can, by accessing textInput's method by refs.
<TextInput ref={input => this.myInput = input} selectTextOnFocus style={{height: 100, width: 100}} defaultValue='Hey there' />
and where you want to select all text programmatically you can
this.myInput.focus()
works on iOS, not sure about android.
Reference : http://facebook.github.io/react-native/releases/0.45/docs/textinput.html#selectionstate
I don't know if there's a better way, but I found a workaround. The text has to be focused first. Here's an example
import React { Component } from 'react';
import { Button, TextInput, findNodeHandle } from 'react-native';
import TextInputState from 'react-native/lib/TextInputState';
class MyComponent extends Component {
render() {
return (
<View style={{ flex: 1, }}>
<Button
title="select text"
onPress={() => {
TextInputState.focusTextInput(findNodeHandle(this.inputRef))
}}
</
<TextInput
selectTextOnFocus
ref={ref => this.inputRef = ref}
/>
</View>
);
}
}
I'm here to share my findings. In a List, you might encounter that selectTextOnFocus is broken. In this case you can use this method selection. From React-Native I found this:
In my case I had trouble with the selectTextOnFocus prop in a list. So I had to add a debounce function to work with selection prop.
const [shouldSelect, setShouldSelect] = useState(undefined);
const onFocus = () =>{
setShouldSelect({start:0, end:String(text).length});
}
const focus = useCallback(_.debounce(onFocus,500),[shouldSelect]);
<TextInput
selection={shouldSelect}
onBlur={()=>setShouldSelect(undefined)}
onFocus={()=>focus()}// this is important
selectTextOnFocus
ref={r=>onRef(r)}
keyboardType={'number-pad'}
autoCorrect={false}
blurOnSubmit={false}
returnKeyType={'done'}
underlineColorIos={'transparent'}
underlineColorAndroid={'white'}
allowFontScaling={false}
value={String(text)}
/>
this.inputRef.focus() sets focus to the TextInput component, and then the flag you set in the attributes selectTextOnFocus does the rest.
Note: For those who wants to use selectTextOnFocus short answer. Actually, it works fine in IOS, but doesn't work in Android.
Thanks to Arnav Yagnik; Following is a similar approach in a functional component:
const inputRef = React.useRef(null);
React.useEffect(() => {
if (inputRef.current) {
console.log('focusing !');
inputRef.current.focus();
}
}, []);
return <TextInput
multiline
label="Amount"
selectTextOnFocus
placeholder="Write Count"
value={stockCount.toString()}
/>