是否有一种可重用的方式来订阅监听器,例如键盘事件。
实际上,我在屏幕的最底部有一个绝对位置的按钮,当键盘弹出时,它浮在顶部,看起来不太好。
因此,当键盘可见时,我将隐藏该按钮,但是如果您在多个屏幕上都有类似的情况,那么现在在每个屏幕上添加订阅都变得很麻烦,我正在这样做。
<form id="form" name="form" action="test.php" method="post">
<input id="writer" type="text" name="writer" value="" placeholder="writer" /> <br />
<textarea id="content" name="content" placeholder="content" ></textarea> <br />
<button type="button" >Submit (no action)</button>
</form>
<button type="button" onClick="changeValue(this, 'content')">Change Content</button>
我不喜欢上述解决方案,因为我必须向我要订阅键盘事件的每个组件添加与订阅相关的代码,而我对javascript还是陌生的,并且仍在学习它。
如果有任何人可以帮助我提供一些一般的解决方案,那就很好了。
答案 0 :(得分:1)
在这些情况下,自定义组件会派上用场。您可以创建一个实现了所需行为的单个组件,然后将该组件添加到要使用的屏幕中。
样品
export default class CustomButton extends Component {
state = {
visible: true
}
componentDidMount() {
// subscribing to keyboard listeners on didMount
this.keyboardDidShowListener = Keyboard.addListener(
'keyboardDidShow',
() => this._toggleVisiblity(false)
);
this.keyboardDidHideListener = Keyboard.addListener(
'keyboardDidHide',
() => this._toggleVisiblity(true)
);
}
_toggleVisiblity = (visible) => {
this.setState({ visible })
}
componentWillUnmount() {
// unsubscribing listeners on unMount
this.keyboardDidShowListener.remove();
this.keyboardDidHideListener.remove();
}
render() {
if (this.state.visible === false) return null
return (
<View
style={{
flex: 1,
justifyContent: 'flex-end',
}}>
<AnimatedBottomButton
title="Done"
onPress={() => Actions.pop()}
style={{
opacity: this.anim5,
transform: [{ scale: this.anim5 }],
marginBottom: Utils.isPhoneX() ? Metrics.doubleBaseMargin : 0,
}}
/>
</View>
);
}
}
class Profile extends Component {
render() {
return (
<ScrollView
style={styles.containerStyle}
bounces={false}
contentContainerStyle={{ flex: 1 }}
keyboardShouldPersistTaps="handled">
{this.renderUserImage()}
{this.renderUserDetail()}
<CustomButton />
</ScrollView>
);
}
}
如果愿意,可以走更远一点,并创建一个HOC。
样品
const withKeyboardEvents = WrappedComponent => {
return class extends Component {
state = {
visible: true,
};
componentDidMount() {
this.keyboardDidShowListener = Keyboard.addListener(
'keyboardDidShow',
() => this._toggleVisiblity(false)
);
this.keyboardDidHideListener = Keyboard.addListener(
'keyboardDidHide',
() => this._toggleVisiblity(true)
);
}
_toggleVisiblity = visible => {
this.setState({ visible });
};
componentWillUnmount() {
this.keyboardDidShowListener.remove();
this.keyboardDidHideListener.remove();
}
render() {
return (
<React.Fragment>
{this.state.visible === true && (
<View
style={{
flex: 1,
justifyContent: 'flex-end',
}}>
<AnimatedBottomButton
title="Done"
onPress={() => Actions.pop()}
style={{
opacity: this.anim5,
transform: [{ scale: this.anim5 }],
marginBottom: Utils.isPhoneX() ? Metrics.doubleBaseMargin : 0,
}}
/>
</View>
)}
<WrappedComponent />
</React.Fragment>
);
}
};
};
class Profile extends Component {
render() {
return (
<ScrollView
style={styles.containerStyle}
bounces={false}
contentContainerStyle={{ flex: 1 }}
keyboardShouldPersistTaps="handled">
{this.renderUserImage()}
{this.renderUserDetail()}
</ScrollView>
);
}
}
export default withKeyboardEvents(Profile)