Focus style for TextInput in react-native
The best way to control the style when the element is focused / blurred is to create your own TextInput wrapper
export const MyAppTextInput = (props) => {
return (
<TextInput
{...props}
/>
);
};
Note that {...props}
will pass in any property you already set or available for TextInput.
Then extend the above component by adding state to apply styles when focus / blur
export const MyAppTextInput = (props) => {
const [isFocused, setIsFocused] = useState(false);
return (
<TextInput
{...props}
style={[props.style, isFocused && {borderWidth: 5, borderColor: 'blue'}]}
onBlur={() => setIsFocused(false)}
onFocus={() => setIsFocused(true)}
/>
);
};
And remember when you use the component to bind the value like in the example (see value={passwordText}
); otherwise the value will disappear on blur as a new render commences after the state change.
<MyAppTextInput
style={styles.input}
value={passwordText}
textContentType="password"
autoCompleteType="off"
secureTextEntry
onChangeText={text => {
setPasswordText(text);
}}
/>
You can of course avoid creating a wrapper but if you have more than one input it will create a mess in your input(s) parent components as you will have to add repeating logic.
Use refs, DirectManipulation and setNativeProps for more performance: https://facebook.github.io/react-native/docs/direct-manipulation.
class MyInput extends Component {
focusedInput = () => {
this.textInput.setNativeProps({
style: { backgroundColor: 'green' }
})
}
blurredInput = () => {
this.textInput.setNativeProps({
style: { backgroundColor: 'yellow' }
})
}
render () {
return <TextInput
ref={c => { this.textInput = c}}
style={styles.textInput}
onFocus={this.focusedInput}
onBlur={this.blurredInput} />
}
}
const stylesObj = { textInput: { height: 50, fontSize: 15, backgroundColor: 'yellow', color: 'black', } }
const styles = StyleSheet.create(stylesObj)
This updates the TextInput component directly without re-rendering the component hierarchy.
You can achieve this by passing in the onFocus and onBlur events to set and unset styles when focused and blurred:
onFocus() {
this.setState({
backgroundColor: 'green'
})
},
onBlur() {
this.setState({
backgroundColor: '#ededed'
})
},
And then, in the TextInput do this:
<TextInput
onBlur={ () => this.onBlur() }
onFocus={ () => this.onFocus() }
style={{ height:60, backgroundColor: this.state.backgroundColor, color: this.state.color }} />
I've set up a full working project here. I hope this helps!
https://rnplay.org/apps/hYrKmQ
'use strict';
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
View,
TextInput
} = React;
var SampleApp = React.createClass({
getInitialState() {
return {
backgroundColor: '#ededed',
color: 'white'
}
},
onFocus() {
this.setState({
backgroundColor: 'green'
})
},
onBlur() {
this.setState({
backgroundColor: '#ededed'
})
},
render: function() {
return (
<View style={styles.container}>
<TextInput
onBlur={ () => this.onBlur() }
onFocus={ () => this.onFocus() }
style={{ height:60, backgroundColor: this.state.backgroundColor, color: this.state.color }} />
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
marginTop:60
}
});
AppRegistry.registerComponent('SampleApp', () => SampleApp);