javascriptreact-native

Focus style for TextInput in react-native


In React Native, how do you change the style of a textInput when it gets focus? Say I have something like

class MyInput extends Component {
    render () {
        return <TextInput style={styles.textInput} />;
    }
};

const stylesObj = {
    textInput: {
        height: 50,
        fontSize: 15,
        backgroundColor: 'yellow',
        color: 'black',
    }
};
const styles = StyleSheet.create(stylesObj);

And I want to change the background color on focus to green.

This documentation leads me to believe that the solution is something like

class MyInput extends Component {
    constructor (props) {
        super(props);
        this.state = {hasFocus: false};
    }

    render () {
        return (<TextInput
            style={this.state.hasFocus ? styles.focusedTextInput : styles.textInput}
            onFocus={this.setFocus.bind(this, true)}
            onBlur={this.setFocus.bind(this, false)}
        />);
    }

    setFocus (hasFocus) {
        this.setState({hasFocus});
    }
};

const stylesObj = {
    textInput: {
        height: 50,
        fontSize: 15,
        backgroundColor: 'yellow',
        color: 'black',
    }
};
const styles = StyleSheet.create({
    ...stylesObj,
    focusedTextInput: {
        ...stylesObj,
        backgroundColor: 'green',
    }
});

Ignoring potential mistakes in the styles structuring, would this be considered correct way to handle it? It seems very verbose to me.


Solution

  • 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);