web-dev-qa-db-fra.com

Masquer/Afficher les composants en natif de réaction

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?

98
Crysfel

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

});
100
Mayank Patel

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
94
Krishan Gupta

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. 

 enter image description here

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;
42
Rajan Twanabashu

dans render (), vous pouvez afficher le fichier JSX de manière conditionnelle ou renvoyer null comme dans:

render(){
    return({yourCondition ? <yourComponent /> : null});
}
15
Mar

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,

10
KuroAku

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

 screencast

10
mauron85

 enter image description here

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})
7
Harshal Valanda

juste utiliser

style={ width:0, height:0 } // to hide
7
amos

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.

6
d4vidi

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;
6
Tonithy

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>
4
Estevão Lucas

Vous pouvez utiliser mon module react-native-display pour afficher/masquer les composants.

2
Danny Michaeli

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;

Here is the result

2
meisam nazari

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})
0
ykay

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>
0
Lim Neo

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>)
}
0
Kiran Chenna

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
  }
});
0
Mehr88sh