Je suis vraiment nouveau dans React Native et je me demande comment masquer/afficher un composant.
Voici mon cas de test:
<TextInput
onFocus={this.showCancel()}
onChangeText={(text) => this.doSearch({input: text})} />
<TouchableHighlight
onPress={this.hideCancel()}>
<View>
<Text style={styles.cancelButtonText}>Cancel</Text>
</View>
</TouchableHighlight>
J'ai un composant TextInput
, ce que je veux, c'est montrer TouchableHighlight
lorsque l'entrée obtient le focus, puis cacher la TouchableHighlight
lorsque l'utilisateur appuie sur le bouton d'annulation.
Je ne sais pas comment "accéder" au composant TouchableHighlight
afin de le masquer/l'afficher à l'intérieur de mes fonctions showCancel/hideCancel
.
De plus, comment puis-je masquer le bouton dès le début?
Je ferais quelque chose comme ça:
var myComponent = React.createComponent({
getInitialState: function () {
return {
showCancel: false,
};
},
toggleCancel: function () {
this.setState({
showCancel: !this.state.showCancel
});
}
_renderCancel: function () {
if (this.state.showCancel) {
return (
<TouchableHighlight
onPress={this.toggleCancel()}>
<View>
<Text style={styles.cancelButtonText}>Cancel</Text>
</View>
</TouchableHighlight>
);
} else {
return null;
}
},
render: function () {
return (
<TextInput
onFocus={this.toggleCancel()}
onChangeText={(text) => this.doSearch({input: text})} />
{this._renderCancel()}
);
}
});
Dans votre fonction de rendu:
{ this.state.showTheThing &&
<TextInput/>
}
Alors juste faire:
this.setState({showTheThing: true}) // to show it
this.setState({showTheThing: false}) // to hide it
Réagissez ou réagissez de manière native, la manière dont le composant masquer/afficher ou ajouter/supprimer ne fonctionne pas comme dans Android ou iOS. La plupart d'entre nous pensent qu'il y aurait une stratégie similaire comme
View.hide = true or parentView.addSubView(childView)
Mais la façon dont réagit le travail indigène est complètement différente. La seule façon d'obtenir ce type de fonctionnalité consiste à inclure votre composant dans votre DOM ou à le supprimer.
Ici, dans cet exemple, je vais définir la visibilité de la vue texte en fonction du clic de bouton.
L'idée sous-jacente à cette tâche est de créer une variable d'état appelée état dont la valeur initiale est définie sur false lorsque l'événement de clic du bouton se produit, puis que cette valeur bascule. Nous allons maintenant utiliser cette variable d'état lors de la création du composant.
import renderIf from './renderIf'
class FetchSample extends Component {
constructor(){
super();
this.state ={
status:false
}
}
toggleStatus(){
this.setState({
status:!this.state.status
});
console.log('toggle button handler: '+ this.state.status);
}
render() {
return (
<View style={styles.container}>
{renderIf(this.state.status)(
<Text style={styles.welcome}>
I am dynamic text View
</Text>
)}
<TouchableHighlight onPress={()=>this.toggleStatus()}>
<Text>
touchme
</Text>
</TouchableHighlight>
</View>
);
}
}
la seule chose à noter dans cet extrait est renderIf
, qui est en fait une fonction qui renvoie le composant qui lui est transmis en fonction de la valeur booléenne qui lui est transmise.
renderIf(predicate)(element)
renderif.js
'use strict';
const isFunction = input => typeof input === 'function';
export default predicate => elemOrThunk =>
predicate ? (isFunction(elemOrThunk) ? elemOrThunk() : elemOrThunk) : null;
dans render (), vous pouvez afficher le fichier JSX de manière conditionnelle ou renvoyer null comme dans:
render(){
return({yourCondition ? <yourComponent /> : null});
}
La plupart du temps, je fais quelque chose comme ça:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {isHidden: false};
this.onPress = this.onPress.bind(this);
}
onPress() {
this.setState({isHidden: !this.state.isHidden})
}
render() {
return (
<View style={styles.myStyle}>
{this.state.isHidden ? <ToHideAndShowComponent/> : null}
<Button title={this.state.isHidden ? "SHOW" : "HIDE"} onPress={this.onPress} />
</View>
);
}
}
Si vous êtes un peu novice en programmation, cette ligne doit vous paraître étrange:
{this.state.isHidden ? <ToHideAndShowComponent/> : null}
Cette ligne est équivalente à
if (this.state.isHidden)
{
return ( <ToHideAndShowComponent/> );
}
else
{
return null;
}
Mais vous ne pouvez pas écrire une condition if/else dans le contenu JSX (par exemple, la partie return () d'une fonction de rendu), vous devrez donc utiliser cette notation.
Cette petite astuce peut être très utile dans de nombreux cas et je vous suggère de l’utiliser dans vos développements car vous pouvez rapidement vérifier une condition.
Cordialement,
Je devais basculer entre deux images. Avec la commutation conditionnelle entre eux, il y avait un délai de 5 secondes sans image affichée.
J'utilise l'approche de la réponse amotée vers le bas. Publier en tant que nouvelle réponse car il est difficile de mettre du code en commentaire avec un formatage correct.
Fonction de rendu:
<View style={styles.logoWrapper}>
<Image
style={[styles.logo, loading ? styles.hidden : {}]}
source={require('./logo.png')} />
<Image
style={[styles.logo, loading ? {} : styles.hidden]}
source={require('./logo_spin.gif')} />
</View>
Modes:
var styles = StyleSheet.create({
logo: {
width: 200,
height: 200,
},
hidden: {
width: 0,
height: 0,
},
});
Hide et Show vue parent de Activity Indicator
constructor(props) {
super(props)
this.state = {
isHidden: false
}
}
Hide and Show as Follow
{
this.state.isHidden ? <View style={style.activityContainer} hide={false}><ActivityIndicator size="small" color="#00ff00" animating={true}/></View> : null
}
Référence complète
render() {
return (
<View style={style.mainViewStyle}>
<View style={style.signinStyle}>
<TextField placeholder='First Name' keyboardType='default' onChangeFirstName={(text) => this.setState({firstName: text.text})}/>
<TextField placeholder='Last Name' keyboardType='default' onChangeFirstName={(text) => this.setState({lastName: text.text})}/>
<TextField placeholder='Email' keyboardType='email-address' onChangeFirstName={(text) => this.setState({email: text.text})}/>
<TextField placeholder='Phone Number' keyboardType='phone-pad' onChangeFirstName={(text) => this.setState({phone: text.text})}/>
<TextField placeholder='Password' secureTextEntry={true} keyboardType='default' onChangeFirstName={(text) => this.setState({password: text.text})}/>
<Button style={AppStyleSheet.buttonStyle} title='Sign up' onPress={() => this.onSignupPress()} color='red' backgroundColor='black'/>
</View>
{
this.state.isHidden ? <View style={style.activityContainer}><ActivityIndicator size="small" color="#00ff00" animating={true}/></View> : null
}
</View>
);
}
On Button appuie sur l'état défini comme suit
onSignupPress() {
this.setState({isHidden: true})
}
Quand tu as besoin de te cacher
this.setState({isHidden: false})
juste utiliser
style={ width:0, height:0 } // to hide
Une option supplémentaire consiste à appliquer le positionnement absolu via styling , en définissant le composant masqué en coordonnées hors écran:
<TextInput
onFocus={this.showCancel()}
onChangeText={(text) => this.doSearch({input: text})}
style={this.state.hide ? {position: 'absolute', top: -200} : {}}
/>
Contrairement à certaines des suggestions précédentes, cela masquerait votre composant de la vue, MAIS il le rendrait également (le conserver dans le DOM), le rendant ainsi réellement invisible.
J'avais le même problème où je voulais afficher/masquer des vues, mais je ne voulais vraiment pas que l'interface utilisateur saute quand des choses ont été ajoutées/supprimées ou nécessairement pour gérer le ré-rendu.
J'ai écrit un composant simple pour le gérer pour moi. Animé par défaut, mais facile à basculer. Je le mets sur GitHub et NPM avec un readme, mais tout le code est ci-dessous.
npm install --save react-native-hideable-view
import React, { Component, PropTypes } from 'react';
import { Animated } from 'react-native';
class HideableView extends Component {
constructor(props) {
super(props);
this.state = {
opacity: new Animated.Value(this.props.visible ? 1 : 0)
}
}
animate(show) {
const duration = this.props.duration ? parseInt(this.props.duration) : 500;
Animated.timing(
this.state.opacity, {
toValue: show ? 1 : 0,
duration: !this.props.noAnimation ? duration : 0
}
).start();
}
shouldComponentUpdate(nextProps) {
return this.props.visible !== nextProps.visible;
}
componentWillUpdate(nextProps, nextState) {
if (this.props.visible !== nextProps.visible) {
this.animate(nextProps.visible);
}
}
render() {
if (this.props.removeWhenHidden) {
return (this.visible && this.props.children);
}
return (
<Animated.View style={{opacity: this.state.opacity}}>
{this.props.children}
</Animated.View>
)
}
}
HideableView.propTypes = {
visible: PropTypes.bool.isRequired,
duration: PropTypes.number,
removeWhenHidden: PropTypes.bool,
noAnimation: PropTypes.bool
}
export default HideableView;
La mise en page de React Native dispose de la propriété display
, similaire à CSS. Valeurs possibles: none
et flex
(par défaut) . https://facebook.github.io/react-native/docs/layout-props#display
<View style={{display: 'none'}}> </View>
Vous pouvez utiliser mon module react-native-display pour afficher/masquer les composants.
Le seul moyen d'afficher ou de masquer un composant dans react native est de vérifier la valeur d'un paramètre d'état d'app tel que state
ou props
. J'ai fourni un exemple complet comme ci-dessous:
import React, {Component} from 'react';
import {View,Text,TextInput,TouchableHighlight} from 'react-native'
class App extends Component {
constructor(props){
super(props);
this.state={
show:false
}
}
showCancel=()=>{
this.setState({show:true})
};
hideCancel=()=>{
this.setState({show:false})
};
renderTouchableHighlight(){
if(this.state.show){
return(
<TouchableHighlight
style={{borderColor:'black',borderWidth:1,marginTop:20}}
onPress={this.hideCancel}>
<View>
<Text>Cancel</Text>
</View>
</TouchableHighlight>
)
}
return null;
}
render() {
return (
<View style={{justifyContent:'center',alignItems:'center',flex:1}}>
<TextInput
style={{borderColor:'black',borderBottomWidth:1}}
onFocus={this.showCancel}
/>
{this.renderTouchableHighlight()}
</View>
);
}
}
export default App;
Si vous avez besoin que le composant reste chargé mais caché, vous pouvez définir l'opacité sur 0. (J'avais besoin de cela pour expo camera par exemple)
//in constructor
this.state = {opacity: 100}
/in component
style = {{opacity: this.state.opacity}}
//when you want to hide
this.setState({opacity: 0})
Très facile. Il suffit de changer en () => this.showCancel () comme ci-dessous:
<TextInput
onFocus={() => this.showCancel() }
onChangeText={(text) => this.doSearch({input: text})} />
<TouchableHighlight
onPress={this.hideCancel()}>
<View>
<Text style={styles.cancelButtonText}>Cancel</Text>
</View>
</TouchableHighlight>
j'utilise simplement la méthode ci-dessous pour masquer ou afficher un bouton. espérons que cela vous aidera. mettre à jour le statut et ajouter masquer css me suffit
constructor(props) {
super(props);
this.state = {
visibleStatus: false
};
}
updateStatusOfVisibility () {
this.setStatus({
visibleStatus: true
});
}
hideCancel() {
this.setStatus({visibleStatus: false});
}
render(){
return(
<View>
<TextInput
onFocus={this.showCancel()}
onChangeText={(text) => {this.doSearch({input: text}); this.updateStatusOfVisibility()}} />
<TouchableHighlight style={this.state.visibleStatus ? null : { display: "none" }}
onPress={this.hideCancel()}>
<View>
<Text style={styles.cancelButtonText}>Cancel</Text>
</View>
</TouchableHighlight>
</View>)
}
En fait, dans le développement iOS par react-native
lorsque j'utilise display: 'none'
ou quelque chose comme ci-dessous:
const styles = StyleSheet.create({
disappearImage: {
width: 0,
height: 0
}
});
L'iOS ne charge rien d'autre du composant Image comme onLoad
ou etc, alors j'ai décidé d'utiliser quelque chose comme ci-dessous:
const styles = StyleSheet.create({
disappearImage: {
width: 1,
height: 1,
position: 'absolute',
top: -9000,
opacity: 0
}
});