Фокусный стиль для TextInput в реагировании

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

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

Ответ 1

Вы можете добиться этого, передав события 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);

Ответ 2

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

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

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

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

+ Ваша таблица стилей по меню:

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

Ответ 3

Используйте refs, DirectManipulation и setNativeProps для большей производительности: 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 = {     ввод текста: {         высота: 50,         fontSize: 15,         backgroundColor: "желтый",         черный цвет',     } }

const styles = StyleSheet.create(stylesObj)

Это обновляет компонент TextInput напрямую, без повторного рендеринга иерархии компонентов.

Ответ 4

Эй, ребята, я вроде использовал идею всякого: р

@Феликс дал мне идею, которая может быть даже чище. (Хотелось бы, чтобы в этом статическом компоненте не было включено состояние, просто чтобы изменить стиль... Но я новичок в этом, чтобы понять это.

вот мое решение:

import React, { Component } from 'react';
import { StyleSheet, TextInput } from 'react-native';

class TxtInput extends Component {
  constructor(props) {
    super(props);
    this.state = {
      style: {},
    };
  }

  onFocus = () => {
    const state = { ...this.state };
    state.style = {
      borderStyle: 'solid',
      borderColor: '#e74712',
    };

    this.setState(state);
  }

  onBlur = () => {
    console.log('on ONBLUR')
    const state = { ...this.state };
    state.style = {};

    this.setState(state);
  }

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

const styles = StyleSheet.create({
  input: {
    color: '#000000',
    fontFamily: 'MuseoSans 700 Italic',
    fontSize: 22,
    borderRadius: 34,
    borderStyle: 'solid',
    borderColor: 'transparent',
    borderWidth: 5,
    backgroundColor: '#ffffff',
    textAlign: 'center',
    width: '25%',
 },
});

export default TxtInput;

Я добавил стиль в массив, чтобы все фактические стили ввода были выполнены для первого свойства массива, а для второго - выделения фокуса и синего цвета.

Надеюсь, поможет

Ответ 5

 <TextInput
 style={{ backgroundColor: 'white', height: 40, width: 100, alignItems: 'center' 
   }} 
 theme={{ colors: { placeholder: 'white', text: 'white', primary: 'white', 
  underlineColor: 'transparent', background: '#003489' } }}
   />