Masquer / Afficher les composants dans react native

Je suis vraiment nouveau pour réagir natif et je me demande Comment puis-je cacher/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 TextInput du composant, ce que je veux, c'est montrer le TouchableHighlight lorsque l'entrée reçoit le focus, puis se cacher la TouchableHighlight lorsque l'utilisateur presse le bouton annuler.

Je ne sais pas comment "accéder" au composant TouchableHighlight afin de le cacher/l'afficher dans mes fonctions showCancel/hideCancel.
Aussi, comment puis-je cacher le bouton dès le début?

89
demandé sur George Kagan 2015-05-15 21:55:28

13 réponses

Je ferais quelque chose comme ceci:

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

});
95
répondu Mayank Patel 2016-11-14 21:05:15

Dans votre fonction de rendu:

{ this.state.showTheThing && 
  <TextInput/>
}

Alors faites simplement:

this.setState({showTheThing: true})  // to show it  
this.setState({showTheThing: false}) // to hide it
76
répondu Krishan Gupta 2017-02-21 14:59:22

Dans react ou react native, le composant way hide / show ou add / remove ne fonctionne pas comme dans android ou iOS. La plupart d'entre nous pensent qu'il y aurait la stratégie similaire comme

View.hide = true or parentView.addSubView(childView)

Mais la façon dont react native work est complètement différente. La seule façon d'obtenir ce type de fonctionnalité est d'inclure votre composant dans votre DOM ou retirer de DOM.

Ici, dans cet exemple, je vais définir la visibilité de la vue texte en fonction du clic du bouton.

entrez la description de l'image ici

L'idée derrière cette tâche est la création d'une variable d'état appelée state ayant la valeur initiale définie sur false lorsque l'événement de clic de bouton se produit, alors sa 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 à remarquer dans cet extrait de code est renderIf, qui est en fait une fonction qui renvoie le composant est passé basé sur la valeur booléenne est passé.

renderIf(predicate)(element)

Renderif.js

'use strict';
const isFunction = input => typeof input === 'function';
export default predicate => elemOrThunk =>
  predicate ? (isFunction(elemOrThunk) ? elemOrThunk() : elemOrThunk) : null;
39
répondu Rajan Twanabashu 2017-02-21 14:55:16

Dans render (), vous pouvez afficher conditionnellement le JSX ou renvoyer null comme dans:

render(){
    return({yourCondition ? <yourComponent /> : null});
}
13
répondu Mar 2018-09-08 22:00:20

J'avais besoin de 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 Amos downvoted. Poster comme nouvelle réponse car il est difficile de mettre du code dans un 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>

Styles:

var styles = StyleSheet.create({
  logo: {
    width: 200,
    height: 200,
  },
  hidden: {
    width: 0,
    height: 0,
  },
});

screencast

9
répondu mauron85 2016-09-12 18:55:38

La plupart du temps, je fais quelque chose comme ceci:

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 nouveau dans la programmation, cette ligne doit vous ê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 consulter rapidement un condition.

Cordialement,

8
répondu KuroAku 2017-11-22 16:05:51

Une option supplémentaire consiste à appliquer 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 le rendrait également (le garderait dans le DOM), le rendant ainsi vraiment invisible .

7
répondu d4vidi 2017-01-11 10:25:26

Il suffit d'utiliser

style={ width:0, height:0 } // to hide
6
répondu amos 2016-02-07 16:55:01

J'ai eu le même problème où je voudrais afficher / masquer les 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 faire face au re-rendu.

J'ai écrit un composant simple pour y faire face pour moi. Animé par défaut, mais facile à basculer. Je l'ai mis sur GitHub et MNP 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
répondu Tonithy 2016-12-31 23:56:06

entrez la description de l'image ici

Masquer Et Afficher parent vue de Activity Indicator

constructor(props) {
  super(props)

  this.state = {
    isHidden: false
  }  
} 

Masquer et Afficher comme suit

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

Sur le bouton appuie sur Définir l'état comme suit

onSignupPress() {
  this.setState({isHidden: true})
}

Quand vous devez cacher

this.setState({isHidden: false})
5
répondu Harshal Valanda 2018-06-30 11:59:06

Vous pouvez utiliser mon module réagir-native-affichage pour afficher/masquer des composants.

2
répondu Danny Michaeli 2017-01-28 11:58:54

Très Facile. Il suffit de changer d' () => cette.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
répondu Lim Neo 2016-01-05 07:04:45

Si vous avez besoin que le composant reste chargé mais caché, vous pouvez définir l'opacité à 0. (J'en avais besoin pour la caméra expo 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
répondu ykay 2018-05-08 11:09:43