Verstecken / Anzeigen von Komponenten in React Native


143

Ich bin wirklich neu in React Native und frage mich, wie ich eine Komponente ausblenden / anzeigen kann.
Hier ist mein Testfall:

<TextInput
    onFocus={this.showCancel()}
    onChangeText={(text) => this.doSearch({input: text})} />

<TouchableHighlight 
    onPress={this.hideCancel()}>
    <View>
        <Text style={styles.cancelButtonText}>Cancel</Text>
    </View>
</TouchableHighlight>

Ich habe eine TextInputKomponente. Ich möchte anzeigen, TouchableHighlightwann der Eingang den Fokus erhält, und dann ausblenden, TouchableHighlightwann der Benutzer die Abbrechen-Taste drückt.

Ich weiß nicht, wie ich auf die TouchableHighlightKomponente "zugreifen" soll , um sie in meinen Funktionen zu verbergen / anzuzeigen showCancel/hideCancel.
Wie kann ich die Schaltfläche von Anfang an ausblenden?


Sie müssen dieses Beispiel überprüfen: Verstecken /
Anzeigen von

Antworten:


134

Ich würde so etwas machen:

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

});

1
Vielen Dank dafür, nur eine kleine Änderung, die ich vornehmen musste: onFocus = {() => this.showCancel ()} Dies muss eine Rückruffunktion sein.
Crysfel

3
return ''return null
Arbeitete

33
Sie können dies auch tun {someBoolVal && <Component />}und es wird nur angezeigt, wenn der Bool-Wert wahr ist.
Nathan Hyland

Dies ist die beste Antwort
Kirill Gusyatin

3
Ich weiß nicht, dass dies die akzeptierte Antwort ist, die nicht die ursprünglich gewünschte Funktionalität zum Ein- / Ausblenden implementiert, sondern stattdessen hinzufügt / entfernt
Muhammad Aref

149

In Ihrer Renderfunktion:

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

Dann machen Sie einfach:

this.setState({showTheThing: true})  // to show it  
this.setState({showTheThing: false}) // to hide it

2
Das hat bei mir funktioniert. Ich bin mir jedoch nicht sicher, warum, wenn ich so etwas wie { this.state.showTheThing && (<Text>foo</Text> && <Text>bar</Text>)}"bar" mache , in der Benutzeroberfläche angezeigt wird. Ich würde erwarten, dass "foo" und "bar" angezeigt werden. Was ich tun musste, um dies zu lösen, ist anzurufen{ this.state.showTheThing && (<Text>foo</Text>} { this.state.showTheThing && (<Text>bar</Text>}
tonatiuhnb

2
Vielleicht funktioniert das? weil die logischen &&Elemente nicht kombinieren{ this.state.showTheThing && (<View><Text>foo</Text><Text>bar</Text></View>)}
Muescha

Dies funktionierte für mich. Ich wollte eine Schaltfläche "Nächster Schritt" anzeigen, wenn ein Benutzer sein Profilbild hochlud. {this.state.hasPic && <Button title="Go to next step" onPress={this._nextStep} />}
Also

Wenn Sie Probleme haben, mehr als eine Komponente anzuzeigen, schließen Sie Ihre Komponente mit einem Fragment ein. z.B. <React.Fragment><Text>Foo</Text><Text>Bar></Text></React.Fragment>
Ben Cull

48

Beim Reagieren oder Reagieren nativ funktioniert die Art und Weise, wie Komponenten ausgeblendet / angezeigt oder hinzugefügt / entfernt werden, nicht wie in Android oder iOS. Die meisten von uns denken, dass es eine ähnliche Strategie geben würde

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

Die Art und Weise, wie einheimische Arbeiten reagieren, ist jedoch völlig anders. Die einzige Möglichkeit, diese Art von Funktionalität zu erreichen, besteht darin, Ihre Komponente in Ihr DOM aufzunehmen oder aus dem DOM zu entfernen.

Hier in diesem Beispiel werde ich die Sichtbarkeit der Textansicht basierend auf dem Klick auf die Schaltfläche einstellen.

Geben Sie hier die Bildbeschreibung ein

Die Idee hinter dieser Aufgabe ist das Erstellen einer Statusvariablen namens state, bei der der Anfangswert auf false gesetzt ist, wenn das Ereignis zum Klicken auf die Schaltfläche auftritt, und der Wert dann umgeschaltet wird. Jetzt werden wir diese Statusvariable während der Erstellung der Komponente verwenden.

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

Das einzige, was in diesem Snippet zu bemerken ist renderIf, ist, dass es sich tatsächlich um eine Funktion handelt, die die an sie übergebene Komponente basierend auf dem an sie übergebenen booleschen Wert zurückgibt.

renderIf(predicate)(element)

renderif.js

'use strict';
const isFunction = input => typeof input === 'function';
export default predicate => elemOrThunk =>
  predicate ? (isFunction(elemOrThunk) ? elemOrThunk() : elemOrThunk) : null;

Clever :) Was ist der Anwendungsfall für den Thunk?
Goldylucks

Haha. Brillant!
Jaseem Abbas

Diese Lösung ist für Anwendungsfälle sinnvoll, in denen ein Dialogfeld nur bei Bedarf gerendert werden muss. Ty!
SoundStage

2
Dies funktioniert nicht, wenn Sie den Status beibehalten und das Element entfernen müssen, um seinen Status zurückzusetzen. Jedes Mal, wenn Sie erneut rendern, wird eine Komponente erstellt.
Daniel Jose Padilla Peña

1
Sie müssen dieses Beispiel überprüfen: Verstecken /
Anzeigen von

20

In render () können Sie JSX bedingt anzeigen oder null zurückgeben wie in:

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

3
Klammern sollten in Zeile 2 erforderlich sein.
jiexishede

Vielen Dank für die einfachste Lösung
Sam

13

Ich musste zwischen zwei Bildern wechseln. Beim bedingten Umschalten zwischen ihnen gab es eine Verzögerung von 5 Sekunden, ohne dass ein Bild angezeigt wurde.

Ich benutze den Ansatz von Downvoted Amos Antwort. Als neue Antwort veröffentlichen, da es schwierig ist, Code mit der richtigen Formatierung in einen Kommentar einzufügen.

Renderfunktion:

<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>

Stile:

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

Screencast


Dadurch bleiben die Komponenten im Speicher, was bei großen Komponenten ein Problem sein kann. Warum nicht die großartigen Beispiele oben verwenden? Sie werden das rechte Bild einfügen und das andere vollständig entfernen ...
AS

4
Jedes dieser Beispiele funktioniert nicht richtig, wenn Sie versuchen, einen animierten Spinner zu erstellen. Wie ich bereits in meiner Antwort auf Android erwähnt habe, wird der Versuch, img für anim gif zu wechseln, eine Verzögerung von 5 Sekunden verursachen, wenn weder png noch gif angezeigt werden. Ich glaube, die Verzögerung wird durch das Laden von GIF in den Speicher verursacht, was einige Zeit dauern kann. Allerdings scheint iOS hier viel bessere Arbeit zu leisten. Wenn Sie mir nicht glauben, versuchen Sie es selbst.
Mauron85

1
Wie bereits erwähnt, ist dies natürlich nicht für jede Komponente die optimale Lösung. Aber meiner Meinung nach zum Laden von Spinner ist es in Ordnung. Es wird schließlich entladen, wenn der Benutzer zu einer anderen Seite wechselt.
Mauron85

13

Die meiste Zeit mache ich so etwas:

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

Wenn Sie neu in der Programmierung sind, muss diese Zeile für Sie seltsam sein:

{this.state.isHidden ? <ToHideAndShowComponent/> : null}

Diese Zeile entspricht

if (this.state.isHidden)
{
  return ( <ToHideAndShowComponent/> );
}
else
{
  return null;
}

Sie können jedoch keine if / else-Bedingung in JSX-Inhalt schreiben (z. B. den return () - Teil einer Renderfunktion), daher müssen Sie diese Notation verwenden.

Dieser kleine Trick kann in vielen Fällen sehr nützlich sein, und ich empfehle Ihnen, ihn in Ihren Entwicklungen zu verwenden, da Sie einen Zustand schnell überprüfen können.

Grüße,


Können Sie bitte näher erläutern, wie Sie <ToHideAndShowComponent />
Ritveak

12

Geben Sie hier die Bildbeschreibung ein

Verbergen und Zeigen Eltern AnsichtActivity Indicator

constructor(props) {
  super(props)

  this.state = {
    isHidden: false
  }  
} 

Verstecken und anzeigen wie folgt

{
   this.state.isHidden ?  <View style={style.activityContainer} hide={false}><ActivityIndicator size="small" color="#00ff00" animating={true}/></View> : null
}

Vollständige Referenz

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 drückt den eingestellten Status wie folgt

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

Wenn du dich verstecken musst

this.setState({isHidden: false})


10

benutz einfach

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

4
Es wäre hilfreich, wenn Sie der Antwort einen Kontext / ein Detail hinzufügen würden.
UditS

Angenommen, Sie haben einen Mechanismus, mit dem Sie entscheiden können, welche Komponente ausgeblendet werden soll, ist diese Antwort sehr nützlich. Sie können jede Komponente, die Sie ausblenden möchten, mit einer Ansicht mit style = {{width: 0, height: 0}} umschließen.
Josh Baker

6
Wie stellen Sie die ursprüngliche Breite und Höhe des Elements wieder her?
Einige Juan

4
Ich verstehe nicht, warum dies abgelehnt wird, aber in vielen Fällen ist es ein guter Rat. Ich muss zwischen animiertem und nicht animiertem GIF wechseln. Das bedingte Umschalten img verursachte Verzögerungen ohne img auf dem Bildschirm. Als Teil des Fixes zeige ich beide Bilder an, aber derjenige, der ausgeblendet werden soll, hat keine Breite und Höhe.
Mauron85

Dadurch bleibt die Komponente im Speicher, was bei großen Komponenten ein Problem sein kann. Warum nicht die großartigen Beispiele oben verwenden? Sie setzen und entfernen Komponente vollständig ...
AS

8
constructor(props) {
    super(props);
    this.state = {
      visible: true,
}
}

Deklarieren Sie sichtbar als falsch, damit standardmäßig Modal / Ansicht ausgeblendet werden

Beispiel = () => {

 this.setState({ visible: !this.state.visible })

}}

** Funktionsaufruf **

{this.state.visible == false ?
        <View>
            <TouchableOpacity
              onPress= {() => this.example()}>   // call function
                          <Text>
                            show view
                          </Text>
            </TouchableOpacity>

</View>
:
 <View>
    <TouchableOpacity
              onPress= {() => this.example()}>
                          <Text>
                            hide view
                          </Text>
            </TouchableOpacity>
</View> 
 }

6

Ich hatte das gleiche Problem, bei dem ich Ansichten ein- / ausblenden wollte, aber ich wollte wirklich nicht, dass die Benutzeroberfläche herumspringt, wenn Dinge hinzugefügt / entfernt werden oder sich unbedingt mit dem erneuten Rendern befassen.

Ich habe eine einfache Komponente geschrieben, um damit für mich umzugehen. Standardmäßig animiert, aber einfach umzuschalten. Ich habe es mit einer Readme- Datei auf GitHub und NPM gestellt , aber der gesamte Code ist unten.

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;

Schön, genau das, wonach ich gesucht habe :)
Adamski

Dies funktioniert am besten und verhält sich wie eine richtige Ansicht, wenn Sie andere Komponenten mit einem Lebenszyklus in die Ansicht einfügen (was nicht funktioniert mit visible && (...).
dB.

6

Eine zusätzliche Option besteht darin, die absolute Positionierung über das Styling anzuwenden und die verborgene Komponente in Koordinaten außerhalb des Bildschirms zu setzen:

<TextInput
    onFocus={this.showCancel()}
    onChangeText={(text) => this.doSearch({input: text})}
    style={this.state.hide ? {position: 'absolute', top: -200} : {}}
/>

Anders als in einigen der vorherigen Vorschläge würde dies Ihre Komponente vor der Ansicht verbergen, ABER sie wird auch gerendert (im DOM behalten), wodurch sie wirklich unsichtbar wird .


2
Diese Idee passt zu mir, danke. Wenn jemand es braucht, schau es dir auch an: gist.github.com/jaysoo/cbb81a07cc22015a72e9
Chaki_Black

3

Wenn die Komponente geladen, aber ausgeblendet bleiben soll, können Sie die Deckkraft auf 0 setzen. (Ich brauchte dies zum Beispiel für die Expo-Kamera.)

//in constructor    
this.state = {opacity: 100}

/in component
style = {{opacity: this.state.opacity}}

//when you want to hide
this.setState({opacity: 0})


2

Das folgende Beispiel codiert in Typoskript mit Hooks.

import React, { useState, useEffect } from "react";

........

const App = () => {

   const [showScrollView, setShowScrollView] = useState(false);

   ......

   const onPress = () => {
    // toggle true or false
    setShowScrollView(!showScrollView);
  }

  ......

      </MapboxGL.ShapeSource>
        <View>{showScrollView ? (<DetailsScrollView />) : null}</View>
      </MapboxGL.MapView>
  ......

}

2
// You can use a state to control wether the component is showing or not
const [show, setShow] = useState(false); // By default won't show

// In return(
{
    show && <ComponentName />
}

/* Use this to toggle the state, this could be in a function in the 
main javascript or could be triggered by an onPress */

show == true ? setShow(false) : setShow(true)

// Example:
const triggerComponent = () => {
    show == true ? setShow(false) : setShow(true)
}

// Or
<SomeComponent onPress={() => {show == true ? setShow(false) : setShow(true)}}/>

3
Während dieser Code das Problem des OP lösen kann, ist es am besten, eine Erklärung beizufügen, wie Ihr Code das Problem des OP behebt. Auf diese Weise können zukünftige Besucher aus Ihrem Beitrag lernen und ihn auf ihren eigenen Code anwenden. SO ist kein Codierungsdienst, sondern eine Ressource für Wissen. Es ist auch wahrscheinlicher, dass qualitativ hochwertige, vollständige Antworten positiv bewertet werden. Diese Funktionen sowie die Anforderung, dass alle Beiträge in sich geschlossen sind, sind einige der Stärken von SO als Plattform, die es von Foren unterscheidet. Sie können bearbeiten, um zusätzliche Informationen hinzuzufügen und / oder Ihre Erklärungen durch Quellendokumentation zu ergänzen.
ysf

1
Aktualisiert, etwas mehr erklärt. Ich hoffe es hilft!
Oyebola

0

Sehr leicht. Wechseln Sie einfach zu () => this.showCancel () wie folgt:

<TextInput
        onFocus={() => this.showCancel() }
        onChangeText={(text) => this.doSearch({input: text})} />

<TouchableHighlight 
    onPress={this.hideCancel()}>
    <View>
        <Text style={styles.cancelButtonText}>Cancel</Text>
    </View>
</TouchableHighlight>

Sie müssen dieses Beispiel überprüfen: Verstecken /
Anzeigen von

0

Ich benutze nur die folgende Methode, um eine Schaltfläche auszublenden oder anzuzeigen. hoffe es wird dir helfen. Nur den Status zu aktualisieren und Hide CSS hinzuzufügen, reicht mir

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

Eigentlich in der iOS-Entwicklung, react-nativewenn ich display: 'none'oder so etwas benutze :

const styles = StyleSheet.create({
  disappearImage: {
    width: 0,
    height: 0
  }
});

Das iOS lädt nichts anderes von der Image-Komponente wie onLoadoder usw., daher habe ich mich für Folgendes entschieden:

const styles = StyleSheet.create({
  disappearImage: {
    width: 1,
    height: 1,
    position: 'absolute',
    top: -9000,
    opacity: 0
  }
});

0

Die einzige Möglichkeit, eine Komponente in React Native anzuzeigen oder auszublenden, besteht darin, einen Wert eines Parameters mit App-Status wie stateoder zu überprüfen props. Ich habe ein vollständiges Beispiel wie folgt angegeben:

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;

Hier ist das Ergebnis


0

Wenn Sie es ausblenden möchten, aber den von der Komponente belegten Platz beibehalten möchten, sollte die visibility: hiddenEinstellung von CSS im Stil der Komponente ausreichen opacity: 0.

Abhängig von der Komponente sind möglicherweise weitere Schritte zum Deaktivieren der Funktionalität erforderlich, da eine Interaktion mit einem unsichtbaren Element möglich ist.


0

Sie können die Bedingungen zum Ein- und Ausblenden der Komponenten verwenden

constructor(){

    super();

    this.state ={

      isVisible:true

    }
  }

  ToggleFunction = () => {

    this.setState(state => ({

      isVisible: !state.isVisible

    }));

  };

  render() {
  
    return (

      <View style={styles.MainContainer}>

      {

        this.state.isVisible ? <Text style= {{ fontSize: 20, color: "red", textAlign: 'center' }}> Hello World! </Text> : null
      }

      <Button title="Toggle Visibility" onPress={this.ToggleFunction} />

      </View>
    );
  }

-2
checkincheckout = () => {
        this.setState({ visible: !this.state.visible })
}

render() {
        return (
{this.state.visible == false ?
        <View style={{ alignItems: 'center', flexDirection: 'row', marginTop: 50 }}>

        <View style={{ flex: 1, alignItems: 'center', flexDirection: 'column' }}>

            <TouchableOpacity onPress={() => this.checkincheckout()}>

                <Text style={{ color: 'white' }}>Click to Check in</Text>

            </TouchableOpacity>

        </View>

    </View>
:
<View style={{ alignItems: 'center', flexDirection: 'row', marginTop: 50 }}>

<View style={{ flex: 1, alignItems: 'center', flexDirection: 'column' }}>

   <TouchableOpacity onPress={() => this.checkincheckout()}>

        <Text style={{ color: 'white' }}>Click to Check out</Text>

    </TouchableOpacity>

</View>

</View>
 }

);
}

das ist alles. Viel Spaß beim Codieren ...

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.