Sembunyikan / Tampilkan komponen dalam reaksi asli


143

Saya benar-benar baru untuk Bereaksi Asli dan saya bertanya-tanya bagaimana saya bisa menyembunyikan / menampilkan komponen.
Inilah kotak ujian saya:

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

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

Saya memiliki TextInputkomponen, yang saya inginkan adalah menunjukkan TouchableHighlightkapan input mendapatkan fokus, lalu sembunyikan TouchableHighlightketika pengguna menekan tombol batal.

Saya tidak tahu cara "mengakses" TouchableHighlightkomponen untuk menyembunyikan / menampilkannya di dalam fungsi saya showCancel/hideCancel.
Juga, bagaimana saya bisa menyembunyikan tombol dari awal?


Jawaban:


135

Saya akan melakukan sesuatu seperti ini:

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
Terima kasih banyak untuk ini, hanya satu perubahan kecil yang perlu saya lakukan: onFocus = {() => this.showCancel ()} ini perlu menjadi fungsi callback.
Crysfel

3
Hanya bekerja untuk saya setelah mengubah return ''toreturn null
k7k0

33
Anda juga dapat melakukannya {someBoolVal && <Component />}dan itu hanya akan ditampilkan jika nilai bool benar.
Nathan Hyland

Ini adalah jawaban terbaik
Kirill Gusyatin

3
Saya tidak tahu ini adalah jawaban yang diterima yang tidak menerapkan tunjukkan / sembunyikan fungsi yang diinginkan asli, tetapi malah menambah / menghapus
Muhammad Aref

150

Dalam fungsi render Anda:

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

Maka lakukan saja:

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

2
Ini berhasil untuk saya. Namun, saya tidak yakin mengapa ketika saya melakukan sesuatu seperti { this.state.showTheThing && (<Text>foo</Text> && <Text>bar</Text>)}hanya "bar" yang ditampilkan di UI. Saya harapkan "foo" dan "bar" akan ditampilkan. Apa yang harus saya lakukan untuk menyelesaikan ini adalah menelepon{ this.state.showTheThing && (<Text>foo</Text>} { this.state.showTheThing && (<Text>bar</Text>}
tonatiuhnb

2
mungkin ini berhasil? karena yang logis &&tidak menggabungkan elemen{ this.state.showTheThing && (<View><Text>foo</Text><Text>bar</Text></View>)}
muescha

Ini bekerja untuk saya, saya ingin menunjukkan tombol "Langkah Berikutnya" ketika pengguna mengunggah profilpicure mereka. jadi kode saya adalah:{this.state.hasPic && <Button title="Go to next step" onPress={this._nextStep} />}
Daggie Blanqx - Douglas Mwangi

Bagi siapa pun yang kesulitan menampilkan lebih dari satu komponen, bungkus komponen Anda dengan sebuah fragmen. misalnya. <React.Fragment><Text>Foo</Text><Text>Bar></Text></React.Fragment>
Ben Cull

48

Dalam bereaksi atau bereaksi asli, cara komponen menyembunyikan / menampilkan atau menambah / menghapus tidak berfungsi seperti di android atau iOS. Sebagian besar dari kita berpikir akan ada strategi serupa

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

Tetapi cara bereaksi pekerjaan asli sama sekali berbeda. Satu-satunya cara untuk mencapai fungsi semacam ini adalah dengan memasukkan komponen Anda dalam DOM Anda atau menghapus dari DOM.

Di sini, dalam contoh ini saya akan mengatur visibilitas tampilan teks berdasarkan klik tombol.

masukkan deskripsi gambar di sini

Gagasan di balik tugas ini adalah membuat variabel keadaan yang disebut status memiliki nilai awal yang disetel ke false ketika peristiwa klik tombol terjadi maka nilainya beralih. Sekarang kita akan menggunakan variabel status ini selama pembuatan komponen.

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

satu-satunya hal yang perlu diperhatikan dalam cuplikan ini adalah renderIfyang sebenarnya merupakan fungsi yang akan mengembalikan komponen yang diteruskan berdasarkan nilai boolean yang diteruskan kepadanya.

renderIf(predicate)(element)

renderif.js

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

Pintar :) apa gunanya untuk thunk?
goldylucks

Ha ha. Cemerlang!
Jaseem Abbas

Solusi ini masuk akal untuk kasus-kasus penggunaan di mana kotak dialog perlu membuat hanya ketika diperlukan. Ty!
SoundStage

2
Ini tidak akan berfungsi jika Anda perlu mempertahankan status, menghapus elemen, mengatur ulang statusnya. jadi setiap kali Anda membuat lagi seperti Anda membuat komponen lagi.
Daniel Jose Padilla Peña


20

di render () Anda dapat menampilkan JSX secara kondisional atau mengembalikan null seperti pada:

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

3
Tanda kurung harus ada di baris 2.
jiexishede

Terima kasih untuk solusi paling sederhana
Sam

13

Saya perlu beralih di antara dua gambar. Dengan peralihan bersyarat di antara mereka ada penundaan 5 detik tanpa gambar ditampilkan.

Saya menggunakan pendekatan dari jawaban amos downvoted. Posting sebagai jawaban baru karena sulit untuk memasukkan kode ke dalam komentar dengan format yang tepat.

Fungsi render:

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

Gaya:

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

screencast


Ini menjaga komponen dalam memori, yang dapat menjadi masalah dengan komponen besar. Mengapa tidak menggunakan contoh-contoh hebat di atas? Mereka akan memasukkan gambar yang tepat dan menghapus yang lain sepenuhnya ...
AS

4
salah satu contoh tersebut tidak berfungsi dengan baik ketika Anda mencoba membuat pemintal animasi. Seperti yang sudah saya sebutkan dalam jawaban saya di android mencoba untuk beralih img untuk anim gif, akan menyebabkan penundaan 5s ketika tidak ada png atau gif yang ditampilkan. Saya percaya penundaan ini disebabkan oleh memuat gif ke dalam memori, yang mungkin memerlukan waktu. Namun iOS tampaknya melakukan pekerjaan yang jauh lebih baik di sini. Jika Anda tidak percaya kepada saya, coba sendiri.
mauron85

1
Tentu saja seperti yang ditunjukkan itu bukan solusi optimal untuk setiap komponen. Tapi IMHO untuk memuat spinner tidak apa-apa. Pada akhirnya akan dibongkar ketika pengguna melakukan transisi ke halaman lain.
mauron85

13

Sebagian besar waktu saya melakukan sesuatu seperti ini:

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

Jika Anda baru mengenal pemrograman, baris ini pasti asing bagi Anda:

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

Baris ini setara dengan

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

Tetapi Anda tidak dapat menulis kondisi if / else dalam konten JSX (mis. Bagian pengembalian () dari fungsi render) sehingga Anda harus menggunakan notasi ini.

Trik kecil ini bisa sangat berguna dalam banyak kasus dan saya menyarankan Anda untuk menggunakannya dalam perkembangan Anda karena Anda dapat dengan cepat memeriksa suatu kondisi.

Salam,


Tolong jelaskan bagaimana Anda mendefinisikan <ToHideAndShowComponent />
Ritveak

12

masukkan deskripsi gambar di sini

Sembunyikan Dan Tampilkan tampilan indukActivity Indicator

constructor(props) {
  super(props)

  this.state = {
    isHidden: false
  }  
} 

Sembunyikan dan Tampilkan sebagai Ikuti

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

Referensi lengkap

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

Pada Tombol, tekan setel status sebagai berikut

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

Ketika Anda perlu bersembunyi

this.setState({isHidden: false})


10

gunakan saja

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

4
Akan sangat membantu jika Anda menambahkan beberapa konteks / detail pada jawabannya.
UditS

Dengan asumsi Anda memiliki mekanisme untuk memutuskan komponen mana yang akan disembunyikan, jawaban ini cukup berguna. Anda dapat membungkus komponen apa pun yang Anda coba sembunyikan dengan Tampilan dengan style = {{width: 0, height: 0}}.
Josh Baker

6
bagaimana Anda mengembalikan elemen ke lebar dan tinggi asli?
Beberapa Juan

4
tidak mengerti mengapa ini diturunkan, tetapi dalam banyak kasus itu adalah saran yang bagus. Saya perlu beralih antara animasi dan non-animasi gif. Img switching bersyarat menyebabkan penundaan tanpa img di layar. Sebagai bagian dari perbaikan, saya menampilkan keduanya img, tetapi orang yang harus disembunyikan memiliki lebar dan tinggi nol.
mauron85

Ini menyimpan komponen dalam memori, yang dapat menjadi masalah dengan komponen besar. Mengapa tidak menggunakan contoh-contoh hebat di atas? Mereka memasukkan dan menghapus komponen sepenuhnya ...
AS

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

menyatakan terlihat salah sehingga dengan modal / tampilan default disembunyikan

contoh = () => {

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

}

** Panggilan fungsi **

{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

Saya memiliki masalah yang sama di mana saya ingin menampilkan / menyembunyikan Tampilan, tetapi saya benar-benar tidak ingin UI melompat ketika hal ditambahkan / dihapus atau harus berurusan dengan rendering ulang.

Saya menulis Komponen sederhana untuk menghadapinya untuk saya. Animasi secara default, tetapi mudah untuk beralih. Saya meletakkannya di GitHub dan NPM dengan readme, tetapi semua kode di bawah.

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;

Bagus, hanya apa yang saya cari :)
Adamski

Ini berfungsi paling baik, dan berperilaku seperti tampilan yang tepat ketika Anda meletakkan komponen lain yang memiliki siklus hidup di dalam tampilan (yang tidak bekerja dengan visible && (...).
dB.

6

Opsi tambahan adalah menerapkan pemosisian absolut melalui gaya , mengatur komponen yang tersembunyi dalam koordinat di luar layar:

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

Tidak seperti di beberapa saran sebelumnya, ini akan menyembunyikan komponen Anda dari tampilan TETAPI juga akan membuatnya (simpan di DOM), sehingga membuatnya benar-benar tidak terlihat .


2
Gagasan ini cocok untuk saya, terima kasih. Jika ada yang butuh, lihat juga: gist.github.com/jaysoo/cbb81a07cc22015a72e9
Chaki_Black

3

Jika Anda memerlukan komponen untuk tetap dimuat tetapi disembunyikan Anda dapat mengatur opacity ke 0. (Saya membutuhkan ini untuk kamera expo misalnya)

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

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

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


2

Contoh berikut adalah pengkodean dalam naskah dengan 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
Meskipun kode ini dapat menyelesaikan masalah OP, yang terbaik adalah menyertakan penjelasan tentang bagaimana kode Anda mengatasi masalah OP. Dengan cara ini, pengunjung masa depan dapat belajar dari pos Anda, dan menerapkannya pada kode mereka sendiri. SO bukan layanan pengkodean, tetapi sumber daya untuk pengetahuan. Juga, kualitas tinggi, jawaban lengkap lebih cenderung terunggulkan. Fitur-fitur ini, bersama dengan persyaratan bahwa semua posting mandiri, adalah beberapa kekuatan SO sebagai platform, yang membedakannya dari forum. Anda dapat mengedit untuk menambahkan info tambahan & / atau untuk melengkapi penjelasan Anda dengan dokumentasi sumber.
ysf

1
Diperbarui, menjelaskan lebih banyak. Semoga ini bisa membantu!
Oyebola

0

Sangat mudah. Cukup ubah ke () => this.showCancel () seperti di bawah ini:

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

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


0

saya hanya menggunakan metode di bawah ini untuk menyembunyikan atau melihat tombol. berharap ini akan membantu anda. hanya memperbarui status dan menambahkan sembunyikan css sudah cukup bagi saya

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

Sebenarnya, dalam pengembangan iOS react-nativesaat saya menggunakan display: 'none'atau sesuatu seperti di bawah ini:

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

IOS tidak memuat komponen gambar seperti onLoadatau dll, jadi saya memutuskan untuk menggunakan sesuatu seperti di bawah ini:

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

0

Satu-satunya cara untuk menampilkan atau menyembunyikan komponen dalam reaksi asli adalah memeriksa nilai parameter keadaan aplikasi seperti stateatau props. Saya memberikan contoh lengkap seperti di bawah ini:

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;

Inilah hasilnya


0

Jika Anda ingin menyembunyikannya, tetapi simpan ruang yang ditempati oleh komponen seperti visibility: hiddenpengaturan css dalam gaya komponenopacity: 0 harus melakukan trik.

Tergantung pada komponen, langkah-langkah lain dalam menonaktifkan fungsionalitas mungkin diperlukan karena interaksi dengan item yang tidak terlihat dimungkinkan.


0

Anda dapat menggunakan kondisi untuk menampilkan dan menyembunyikan komponen

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

);
}

itu saja. nikmati kode Anda ...

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.