Reaksiyon yerelindeki bileşenleri gizle / göster


143

React Native için gerçekten yeniyim ve bir bileşeni nasıl gizleyebileceğimi / gösterebileceğimi merak ediyorum.
İşte benim test durumum:

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

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

Bir TextInputbileşenim var, göstermek istediğimTouchableHighlight girişin ne zaman odaklanacağını göstermek, ardından TouchableHighlightkullanıcı iptal düğmesine bastığında gizlemek .

TouchableHighlightİşlevlerimin içinde gizlemek / göstermek için bileşene nasıl "erişileceğini" bilmiyorum showCancel/hideCancel.
Ayrıca, düğmeyi en başından nasıl gizleyebilirim?


bu örneği incelemeniz gerekiyor:
Reat

Yanıtlar:


135

Böyle bir şey yapardım:

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
Bunun için çok teşekkür ederim, yapmam gereken sadece küçük bir değişiklik: onFocus = {() => this.showCancel ()} bunun bir geri çağırma işlevi olması gerekiyor.
Crysfel

3
Sadece değiştirdikten sonra benim için çalıştı return ''etmekreturn null
k7k0

33
Ayrıca yapabilirsiniz {someBoolVal && <Component />}ve yalnızca bool değerinin doğru olup olmadığını gösterir.
Nathan Hyland

Bu en iyi cevap
Kirill Gusyatin

3
Bu istenen orijinal göstermek göstermek / gizlemek yerine kabul edilen cevap olduğunu bilmiyorum, ama bunun yerine eklemek / kaldırmak
Muhammed Aref

150

Oluşturma işlevinizde:

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

Sonra sadece yapın:

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

2
Bu benim için çalıştı. Ancak, { this.state.showTheThing && (<Text>foo</Text> && <Text>bar</Text>)}yalnızca "bar" gibi bir şey yaptığımda kullanıcı arayüzünde neden gösterildiğinden emin değilim . "Foo" ve "bar" görüntüleneceğini beklenir. Bunu çözmek için yapmam gereken şey şu demek{ this.state.showTheThing && (<Text>foo</Text>} { this.state.showTheThing && (<Text>bar</Text>}
tonatiuhnb

2
belki bu işe yarar? çünkü mantıksal &&unsurları birleştirmez{ this.state.showTheThing && (<View><Text>foo</Text><Text>bar</Text></View>)}
muescha

Bu benim için çalıştı, bir kullanıcı profil pedikürünü yüklediğinde "Sonraki Adım" düğmesini göstermek istedim. kodum şuydu:{this.state.hasPic && <Button title="Go to next step" onPress={this._nextStep} />}
Daggie Blanqx - Douglas Mwangi

Birden fazla bileşen göstermekle uğraşan herkes için bileşeninizi bir parça ile sarın. Örneğin. <React.Fragment><Text>Foo</Text><Text>Bar></Text></React.Fragment>
Ben Cull

48

Yerel olarak tepki verme veya tepki verme sırasında, bileşenin gizleme / gösterme veya ekleme / kaldırma yöntemi android veya iOS'ta olduğu gibi çalışmaz. Birçoğumuz benzer bir strateji olacağını düşünüyoruz

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

Ancak yerel çalışmalara tepki verme şekli tamamen farklıdır. Bu tür bir işlevsellik elde etmenin tek yolu, bileşeninizi DOM'nize dahil etmek veya DOM'dan kaldırmaktır.

Bu örnekte, düğme tıklamasına bağlı olarak metin görünümünün görünürlüğünü ayarlayacağım.

resim açıklamasını buraya girin

Bu görevin arkasındaki fikir, button click olayı gerçekleştiğinde başlangıç ​​değeri false olarak ayarlanmış durum adı verilen bir durum değişkeni oluşturmaktır. Şimdi bu durum değişkenini bileşen oluşturulurken kullanacağız.

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

bu snippet'te fark edilmesi gereken tek şey renderIf, aslında kendisine iletilen bileşeni, kendisine iletilen boole değerine göre döndürecek bir işlevdir.

renderIf(predicate)(element)

renderif.js

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

Zeki :) thunk için kullanım durumu nedir?
goldylucks

Haha. Parlak!
Jaseem Abbas

Bu çözüm, bir iletişim kutusunun yalnızca gerektiğinde görüntülenmesi gereken kullanım durumları için anlamlıdır. Ty!
SoundStage

2
Durumu korumanız, öğeyi sıfırlama durumunu sıfırlamanız gerekiyorsa bu çalışmaz. böylece her yeniden oluşturma işleminizde bileşen tekrar oluşturursunuz.
Daniel Jose Padilla Peña

1
bu örneği incelemeniz gerekiyor:
Reat

20

render () içinde JSX'i koşullu olarak gösterebilir veya null değerini aşağıdaki gibi döndürebilirsiniz:

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

3
Parantez 2. satırda
istenmelidir

En basit çözüm için teşekkürler
Sam

13

İki görüntü arasında geçiş yapmam gerekiyordu. Aralarında koşullu geçiş olduğunda, hiçbir görüntü gösterilmeden 5 saniye gecikme oldu.

İndirilmiş amos cevabından yaklaşım kullanıyorum. Yeni yanıt olarak yayınlamak, çünkü kodu uygun biçimlendirmeyle yorum yapmak zor.

Render işlevi:

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

stiller:

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

screencast


Bu, bileşenleri büyük belleklerle ilgili bir sorun olabilen bellekte tutar. Neden yukarıdaki harika örnekleri kullanmıyorsunuz? Doğru resmi ekleyecek ve diğerini tamamen kaldıracaklar ...
AS

4
Animasyonlu döndürücü oluşturmaya çalıştığınızda bu örneklerden hiçbiri düzgün çalışmıyor. Animasyonlu gif için img'yi değiştirmeye çalıştığım Android'de cevabımda daha önce de belirttiğim gibi, hiçbir png veya gif gösterilmediğinde 5s gecikmesine neden olacak. Gecikmenin gif'i belleğe yüklemesinden kaynaklandığına inanıyorum, bu biraz zaman alabilir. Ancak iOS burada daha iyi iş yapıyor gibi görünüyor. Bana inanmıyorsanız, kendiniz deneyin.
mauron85

1
Elbette belirtildiği gibi, her bileşen için en uygun çözüm değildir. Ancak IMHO, spinner'ı yüklemek için gayet iyi. Kullanıcı başka bir sayfaya geçiş yaptığında sonunda kaldırılacaktır.
mauron85

13

Çoğu zaman böyle bir şey yapıyorum:

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

Programlamaya yeniyseniz, bu satır size garip gelmelidir:

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

Bu çizgi şuna eşdeğerdir:

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

Ancak JSX içeriğine bir if / else koşulu yazamazsınız (örneğin, bir oluşturma işlevinin return () parçası), bu gösterimi kullanmanız gerekir.

Bu küçük hile birçok durumda çok yararlı olabilir ve gelişmelerinizde kullanmanızı öneririm, çünkü bir durumu hızlı bir şekilde kontrol edebilirsiniz.

Saygılarımızla,


Lütfen <ToHideAndShowComponent />
Ritveak

12

resim açıklamasını buraya girin

Kullanıcısının üst görünümünü Gizle ve GösterActivity Indicator

constructor(props) {
  super(props)

  this.state = {
    isHidden: false
  }  
} 

Aşağıdaki Gibi Gizle ve Göster

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

Tam referans

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

Açık Düğmesi ayar durumuna aşağıdaki gibi basar

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

Saklanman gerektiğinde

this.setState({isHidden: false})


10

sadece kullan

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

4
Cevaba bir miktar içerik / ayrıntı eklerseniz yardımcı olur.
UditS

Hangi bileşenin gizleneceğine karar vermek için bir mekanizmanız olduğunu varsayarsak, bu cevap oldukça yararlıdır. Gizlemeye çalıştığınız herhangi bir bileşeni, style = {{width: 0, height: 0}} olan bir Görünüm ile sarabilirsiniz.
Josh Baker

6
öğeyi orijinal genişlik ve yüksekliğe nasıl geri yüklersiniz?
Bazı Juan

4
bunun neden reddedildiğini anlamıyorum, ancak çoğu durumda iyi bir tavsiye. Animasyonlu ve animasyonlu olmayan gif arasında geçiş yapmam gerekiyor. Koşullu anahtarlama img, ekranda img olmadan gecikmelere neden oldu. Düzeltmenin bir parçası olarak, hem img'yi görüntülüyorum, ancak gizlenmesi gereken kişinin genişliği ve yüksekliği sıfır.
mauron85

Bu, bileşeni büyük bileşenlerle ilgili bir sorun olabilecek bellekte tutar. Neden yukarıdaki harika örnekleri kullanmıyorsunuz? Bileşeni tamamen takıp
AS

6

Görüntülemeleri göstermek / gizlemek istediğim aynı sorunu yaşadım, ancak işler eklendiğinde / kaldırıldığında veya mutlaka yeniden oluşturma ile uğraşmak için arayüzün atlamasını gerçekten istemiyordum.

Onunla başa çıkmak için basit bir Bileşen yazdım. Varsayılan olarak animasyonludur, ancak geçişi kolaydır. Benioku ile GitHub ve NPM üzerine koydum , ancak tüm kod aşağıda.

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;

İyi olan, aradığım şey :)
Adamski

Bu en iyi şekilde çalışır ve görünüm içinde bir yaşam döngüsüne sahip diğer bileşenleri koyduğunuzda uygun bir görünüm gibi davranır (ile çalışmaz visible && (...).
dB.

6

Ek bir seçenek, gizli bileşeni ekran dışı koordinatlarda ayarlayarak stil aracılığıyla mutlak konumlandırma uygulamaktır :

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

Önceki önerilerin bazılarından farklı olarak, bu, bileşeninizi görünümden gizleyecektir, ancak aynı zamanda onu (DOM'da saklayacak), böylece gerçekten görünmez hale getirecektir .


2
Bu fikir benim için uygun, teşekkürler. Herhangi birinin
Chaki_Black

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

görünür kimliğini bildir, böylece varsayılan mod / görünüm gizle

örnek = () => {

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

}

** İşlev çağrısı **

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

3

Bileşenin yüklü kalması ancak gizli kalması gerekiyorsa, opaklığı 0 olarak ayarlayabilirsiniz. (Örneğin, expo kamera için buna ihtiyacım vardı)

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

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

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


2

Aşağıdaki örnek, Hooks ile daktiloda kodlamadır.

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
Bu kod OP sorununu çözse de, kodunuzun OP sorununu nasıl ele aldığına dair bir açıklama eklemek en iyisidir. Bu şekilde, gelecekteki ziyaretçiler yayınınızdan bilgi edinebilir ve kendi kodlarına uygulayabilir. SO bir kodlama servisi değil, bilgi kaynağıdır. Ayrıca, yüksek kaliteli ve eksiksiz cevapların kaldırılması daha olasıdır. Bu özellikler, tüm yayınların bağımsız olması şartıyla birlikte, bir platform olarak SO'yu forumlardan ayıran güçlü yönlerinden bazılarıdır. Ek bilgi eklemek ve / veya açıklamalarınızı kaynak belgelerle desteklemek için düzenleyebilirsiniz.
ysf

1
Güncellenmiş, biraz daha açıkladı. Umarım yardımcı olur!
Oyebola

0

Çok kolay. Aşağıdaki gibi () => this.showCancel () olarak değiştirin:

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

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

bu örneği incelemeniz gerekiyor:
Reat

0

ben sadece bir düğme gizlemek veya görüntülemek için aşağıdaki yöntemi kullanıyorum. size yardımcı olacağını umuyoruz. sadece durumu güncellemek ve hide css eklemek benim için yeterli

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

Aslında, iOS geliştirmede aşağıdaki gibi bir şey react-nativekullandığımda display: 'none'veya aşağıdaki gibi bir şey:

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

İOS, Image bileşeninin vb.Gibi başka bir şey yüklemediğinden onLoad, aşağıdaki gibi bir şey kullanmaya karar verdim:

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

0

Reaksiyon ana dilinde bir bileşeni göstermenin veya gizlemenin tek yolu, uygulama durumu parametresinin stateveya gibi bir değerini kontrol etmektir props. Aşağıdaki gibi tam bir örnek verdim:

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;

İşte sonuç


0

Gizlemek istiyorsanız, ancak visibility: hiddenbileşenin stilindeki css ayarı gibi bileşen tarafından işgal edilen alanı tutmak opacity: 0hile yapmalıdır.

Bileşene bağlı olarak, görünmez bir öğe ile etkileşim mümkün olduğundan işlevselliği devre dışı bırakma konusunda başka adımlar gerekebilir.


0

Bileşenleri göstermek ve gizlemek için koşulları kullanabilirsiniz

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

);
}

bu kadar. kodlamanın tadını çıkar ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.