Javascript react-native 中 TextInput 的焦点样式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34087459/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 15:54:04  来源:igfitidea点击:

Focus style for TextInput in react-native

javascriptreact-native

提问by Gorm Casper

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

在 React Native 中,textInput当a获得焦点时如何更改样式?说我有类似的东西

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.

我想将焦点的背景颜色更改为green.

This documentationleads 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.

忽略样式结构中的潜在错误,这会被认为是正确的处理方式吗?这对我来说似乎很冗长。

回答by Nader Dabit

You can achieve this by passing in the onFocus and onBlur events to set and unset styles when focused and blurred:

您可以通过传入 onFocus 和 onBlur 事件来在聚焦和模糊时设置和取消设置样式来实现此目的:

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

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

And then, in the TextInput do this:

然后,在 TextInput 中执行以下操作:

<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

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

回答by colemerrick

Use refs, DirectManipulation and setNativeProps for more performance: https://facebook.github.io/react-native/docs/direct-manipulation.

使用 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 = { textInput: { height: 50, fontSize: 15, backgroundColor: 'yellow', color: 'black', } }

const styleObj = { textInput: { height: 50, fontSize: 15, backgroundColor: 'yellow', color: 'black', } }

const styles = StyleSheet.create(stylesObj)

const 样式 = StyleSheet.create(stylesObj)

This updates the TextInput component directly without re-rendering the component hierarchy.

这会直接更新 TextInput 组件,而无需重新渲染组件层次结构。

回答by Antonio Daniel Rodriguez

Nader Dabit′s pointed me to do something similar -- using the state for styles -- but I think it can be done in a cleaner way if you created separate styles for the focused and unfocused style and pass only the style ID as follows:

Nader Dabit 指出我可以做一些类似的事情——使用样式的状态——但我认为如果你为聚焦和非聚焦样式创建单独的样式并且只传递样式 ID,我认为可以以更简洁的方式完成,如下所示:

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

in render -- referencing by styleID in this.state.style, note how the different styles are passed as an Array:

在渲染中——通过 styleID in 引用this.state.style,注意不同的样式是如何作为数组传递的:

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

+ your stylesheet à la carte:

+您的单点样式表:

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

回答by Joseph Briggs

Hey guys I kinda used everyones idea :p

嘿伙计们,我有点使用大家的想法:p

@Felix gave me an idea that might be perhaps even cleaner. (I would have loved to not have included state though on this static component, just to change styling... But I am to new to this to figure that out.

@Felix 给了我一个可能更简洁的想法。(我很想在这个静态组件上不包含状态,只是为了改变样式......但我是新手来弄清楚这一点。

here was my solution:

这是我的解决方案:

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;

I added the style into an array, have all the actual input styling done on the first property of the array and the second one the nit picking of the focus and blue.

我将样式添加到数组中,在数组的第一个属性上完成所有实际输入样式,在第二个属性上完成焦点和蓝色的 nit 选择。

Hope it helps

希望能帮助到你

回答by patel jigar

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

回答by Gabriel P.

The best way to control the style when the element is focused / blurred is to create your own TextInput wrapper

当元素聚焦/模糊时控制样式的最佳方法是创建自己的 TextInput 包装器

export const MyAppTextInput = (props) => {
  return (
    <TextInput
      {...props}
    />
  );
};

Note that {...props}will pass in any property you already set or available for TextInput.

请注意,{...props}它将传入您已设置或可用于 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.

请记住,当您像示例中那样使用组件绑定值时(请参阅 参考资料value={passwordText});否则,在状态更改后开始新的渲染时,该值将在模糊时消失。

<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.

您当然可以避免创建包装器,但是如果您有多个输入,它将在您的输入父组件中造成混乱,因为您将不得不添加重复逻辑。