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
Focus style for TextInput in react-native
提问by Gorm Casper
In React Native, how do you change the style of a textInput
when 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.
您当然可以避免创建包装器,但是如果您有多个输入,它将在您的输入父组件中造成混乱,因为您将不得不添加重复逻辑。