Стиль фокуса для TextInput в react-native

в React Native, как вы меняете стиль textInput, когда он получает фокус? Скажем, у меня есть что-то вроде

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

и я хочу изменить цвет фона на фокус green.

документация приводит меня к мысли, что решение это что-то вроде

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',
    }
});

игнорируя потенциальные ошибки в структурировании стилей, будет ли это считаться правильным способом справиться с этим? Мне это кажется очень многословным.

2 ответов


вы можете достичь этого, передавая события onFocus и onBlur для установки и отмены стилей при фокусировке и размытости:

  onFocus() {
    this.setState({
        backgroundColor: 'green'
    })
  },

  onBlur() {
    this.setState({
      backgroundColor: '#ededed'
    })
  },

и затем, в TextInput сделайте следующее:

<TextInput 
    onBlur={ () => this.onBlur() }
    onFocus={ () => this.onFocus() }
    style={{ height:60, backgroundColor: this.state.backgroundColor, color: this.state.color }}  />

Я создал полный рабочий проект здесь. Надеюсь, это поможет!

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

Nader Dabits указал мне сделать что-то подобное-используя состояние для стилей-но я думаю, что это можно сделать более чистым способом, если вы создали отдельные стили для сфокусированного и расфокусированного стиля и передаете только идентификатор стиля следующим образом:

getInitialState() {
  return { style: styles.textinput_unfocused }
}
onFocus() {
  this.setState({ style: styles.textinput_focused })
}
onBlur() {
  this.setState({ style: styles.textinput_unfocused })
}

in render -- ссылка на styleID в this.state.style обратите внимание, как различные стили передаются в виде массива:

<TextInput 
  onBlur={ () => this.onBlur() }
  onFocus={ () => this.onFocus() }
  style={ [styles.textinput, this.state.style] }  />

+ ваша таблица стилей à la carte:

textinput_focused: {
  backgroundColor: 'red',
  color: 'white'
}
textinput_unfocused: {
  backgroundColor: 'green'
}