反应原生的TextInput焦点样式

Gor*_*per 16 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);
Run Code Online (Sandbox Code Playgroud)

我想改变焦点的背景颜色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',
    }
});
Run Code Online (Sandbox Code Playgroud)

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

Nad*_*bit 30

您可以通过传入onFocus和onBlur事件来实现这一点,以便在聚焦和模糊时设置和取消设置样式:

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

  onBlur() {
    this.setState({
      backgroundColor: '#ededed'
    })
  },
Run Code Online (Sandbox Code Playgroud)

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

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

我已经建立了一个完整的工作项目在这里.我希望这有帮助!

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);
Run Code Online (Sandbox Code Playgroud)

  • 如果您在视图中有多个&lt;TextInput&gt;并且只想设置当前焦点的样式,该怎么办? (3认同)

col*_*ick 8

使用 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} />
  }
Run Code Online (Sandbox Code Playgroud)

}

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

const 样式 = StyleSheet.create(stylesObj)

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


Gab*_* P. 6

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

export const MyAppTextInput = (props) => {
  return (
    <TextInput
      {...props}
    />
  );
};
Run Code Online (Sandbox Code Playgroud)

请注意,{...props}它将传入您已设置或可用于 TextInput 的任何属性。

然后通过添加状态来扩展上述组件以在聚焦/模糊时应用样式

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)}
    />
  );
};
Run Code Online (Sandbox Code Playgroud)

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

<MyAppTextInput
          style={styles.input}
          value={passwordText}
          textContentType="password"
          autoCompleteType="off"
          secureTextEntry
          onChangeText={text => {
            setPasswordText(text);
          }}
        />
Run Code Online (Sandbox Code Playgroud)

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


Aja*_*van 5

您可以创建一个状态来跟踪输入状态并使用该状态来切换样式。这是一个简单的例子

const App = () => {
  const [isActive, setActive] = useState(false);

  return (
    <TextInput style={{ color: isActive ? 'black' : 'grey' }} onFocus={() => setActive(true)} onBlur={() => setActive(false)}/>
  );
}
Run Code Online (Sandbox Code Playgroud)