反応ネイティブでコンポーネントを非表示/表示


143

React Nativeは本当に初めてで、コンポーネントを非表示/表示する方法を知りたいです。
これが私のテストケースです:

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

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

私が持っているTextInputコンポーネントを、私がしたいことを示すことですTouchableHighlight入力がフォーカスを取得したときに、その後、非表示TouchableHighlightのユーザキャンセルボタンを押したとき。

TouchableHighlight関数内でコンポーネントを非表示/表示するためにコンポーネントに「アクセス」する方法がわかりませんshowCancel/hideCancel
また、ボタンを最初から非表示にするにはどうすればよいですか?


この例を確認する必要があります
。reactnativeで

回答:


135

私はこのようなことをします:

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
本当にありがとうございました。私がしなければならない小さな変更が1つだけあります:onFocus = {()=> this.showCancel()}これはコールバック関数である必要があります。
Crysfel

3
に変更した後のみ私のために働いreturn ''return null
k7k0

33
実行することもでき{someBoolVal && <Component />}、ブール値がtrueの場合にのみ表示されます。
Nathan Hyland 2016

これが最良の答えです
Kirill Gusyatin

3
これが受け入れられた答えであることはわかりませんが、元の目的の機能の表示/非表示を実装せず、代わりに追加/削除します
Muhammad Aref

150

あなたのレンダー関数で:

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

次に、ちょうど行います:

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

2
これでうまくいきました。しかし、なぜ{ this.state.showTheThing && (<Text>foo</Text> && <Text>bar</Text>)}「バー」だけがUIに表示されるようなことをしたのか、よくわかりません。「foo」と「bar」が表示されると思います。これを解決するために私がしなければならなかったのは、電話することです{ this.state.showTheThing && (<Text>foo</Text>} { this.state.showTheThing && (<Text>bar</Text>}
tonatiuhnb

2
多分これはうまくいきますか?論理的な&&要素を結合しないため{ this.state.showTheThing && (<View><Text>foo</Text><Text>bar</Text></View>)}
muescha

これは私にとってはうまくいきました、ユーザーが自分のプロフィール画像をアップロードしたときに「次のステップ」ボタンを表示したかったのです。私のコードはでしたので:{this.state.hasPic && <Button title="Go to next step" onPress={this._nextStep} />}
Daggie Blanqx -ダグラスMwangi

複数のコンポーネントの表示に苦労している人は、コンポーネントをフラグメントでラップしてください。例えば。<React.Fragment><Text>Foo</Text><Text>Bar></Text></React.Fragment>
Ben Cull

48

反応またはネイティブで反応するコンポーネントの非表示/表示または追加/削除の方法は、AndroidまたはiOSのように機能しません。私たちのほとんどは、次のような同様の戦略があると思います

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

しかし、ネイティブの作業に反応する方法は完全に異なります。この種の機能を実現する唯一の方法は、コンポーネントをDOMに含めるか、DOMから削除することです。

この例では、ボタンのクリックに基づいてテキストビューの可視性を設定します。

ここに画像の説明を入力してください

このタスクの背後にある考え方は、ボタンクリックイベントが発生したときに値が切り替わるときに初期値がfalseに設定された状態と呼ばれる状態変数を作成することです。次に、コンポーネントの作成中にこの状態変数を使用します。

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

このスニペットで唯一気付くのはrenderIf、渡されたブール値に基づいて渡されたコンポーネントを実際に返す関数です。

renderIf(predicate)(element)

renderif.js

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

賢い:)サンクのユースケースは何ですか?
goldylucks 2016年

はは。鮮やかさ!
Jaseem Abbas

このソリューションは、ダイアログボックスが必要なときにだけレンダリングする必要があるユースケースに適しています。タイ!
SoundStage 2017年

2
ステータスを維持する必要がある場合は機能しません。要素を削除して状態をリセットしてください。したがって、再度レンダリングするたびに、コンポーネントを再作成するようなものです。
Daniel Jose PadillaPeña18年

1
この例を確認する必要があります
。reactnativeで

20

render()では、条件付きでJSXを表示するか、次のようにnullを返すことができます。

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

3
括弧は2行目で必要とされなければならない
jiexishede

最も簡単な解決策をありがとう
Sam

13

2つの画像を切り替える必要がありました。それらの間の条件付き切り替えでは、画像が表示されずに5秒の遅延がありました。

私は反対投票されたamos回答からのアプローチを使用しています。適切なフォーマットでコードをコメントに入れるのが難しいため、新しい回答として投稿します。

レンダリング機能:

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

スタイル:

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

スクリーンキャスト


これにより、コンポーネントがメモリに保持されます。これは、大きなコンポーネントで問題になる可能性があります。上記の優れた例を使用してみませんか?彼らは正しい写真を挿入し、他の写真を完全に削除します...
AS

4
アニメーションスピナーを作成しようとすると、これらの例のいずれも正しく機能しません。Androidでアニメーションgifのimgを切り替えようとする私の回答ですでに述べたように、pngもgifも表示されない場合、5秒の遅延が発生します。遅延はgifのメモリへの読み込みが原因で発生すると考えられます。ただし、iOSの方がはるかに優れています。私を信じないなら、自分で試してみてください。
mauron85 2016年

1
もちろん、指摘したように、すべてのコンポーネントに最適なソリューションというわけではありません。しかし、スピナーをロードするための私見はそれで結構です。ユーザーが別のページに遷移すると、最終的にアンロードされます。
mauron85 2016年

13

ほとんどの場合、私はこのようなことをしています:

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

プログラミングに慣れていない場合、この行は奇妙なものになるはずです。

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

この行は、

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

ただし、JSXコンテンツにif / else条件(たとえば、レンダリング関数のreturn()部分)を記述できないため、この表記を使用する必要があります。

この小さなトリックは多くの場合非常に役立ちます。状態をすばやく確認できるため、開発で使用することをお勧めします。

よろしく、


<ToHideAndShowComponent />の定義方法について詳しく教えてください
Ritveak

12

ここに画像の説明を入力してください

親ビューの表示表示Activity Indicator

constructor(props) {
  super(props)

  this.state = {
    isHidden: false
  }  
} 

フォローとして表示および表示

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

完全なリファレンス

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

ボタンを押すと、次のように状態が設定されます

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

あなたが隠す必要があるとき

this.setState({isHidden: false})

11

React Nativeのレイアウトは、displayCSSと同様にプロパティをサポートしています。可能な値:noneand flex(デフォルト)。 https://facebook.github.io/react-native/docs/layout-props#display

<View style={{display: 'none'}}> </View>

2
これをposition: absoluteで使用しないように注意してください。実際には非表示にはなりません。0.54から0.59(少なくとも)の既知のバグ:github.com/facebook/react-native/issues/18415
Joshua Pinter

10

ただ使う

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

4
回答にコンテキスト/詳細を追加すると役立つでしょう。
UditS 2016

非表示にするコンポーネントを決定するメカニズムがあるとすると、この回答は非常に役立ちます。非表示にしようとしているコンポーネントは、style = {{width:0、height:0}}のビューでラップできます。
Josh Baker

6
どのように要素を元の幅と高さに復元しますか?
一部のフアン

4
なぜこれが反対票を投じられるのか理解できませんが、多くの場合それは良いアドバイスです。アニメーションGIFと非アニメーションGIFを切り替える必要があります。条件付きの切り替えimgにより、画面にimgがない状態で遅延が発生しました。修正の一環として、両方のimgを表示していますが、非表示にする必要があるものは、幅と高さがゼロです。
mauron85 2016

これにより、コンポーネントがメモリに保持されます。これは、大きなコンポーネントで問題になる可能性があります。上記の優れた例を使用してみませんか?彼らはコンポーネントを完全に挿入および削除します...
AS

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

デフォルトでモーダル/ビューが非表示になるように、表示されるfalseを宣言します

例=()=> {

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

}

**関数呼び出し**

{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

ビューを表示/非表示にするのと同じ問題がありましたが、物事が追加/削除されたとき、または必ずしも再レンダリングを処理するときにUIをジャンプさせたくありませんでした。

私はそれを処理するための簡単なコンポーネントを書きました。デフォルトでアニメーション化されていますが、簡単に切り替えることができます。READMEを使用してGitHubNPMに配置しましたが、すべてのコードは以下のとおりです。

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;

素敵なもの、ちょうど私が探していたもの:)
Adamski

これは最高の作品、そしてあなたと仕事をしませんビュー(内部のライフサイクルを持っている他のコンポーネントを配置し、適切なビューのように振舞うvisible && (...)
。デシベル

6

追加オプションは、スタイル設定を介して絶対配置を適用し、非表示の座標に非表示コンポーネントを設定することです。

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

以前の提案のいくつかとは異なり、このビューから、あなたのコンポーネントを非表示となるだけでなく、このように、それが本当になって、(DOMに保管してください)、それをレンダリングします目に見えません


2
このアイデアは私に合っています、ありがとう。誰かが必要なら、それも見てください:gist.github.com/jaysoo/cbb81a07cc22015a72e9
Chaki_Black

3

コンポーネントをロードしたまま隠したままにする必要がある場合は、不透明度を0に設定できます(たとえば、これはエキスポカメラに必要でした)。

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

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

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


2

次の例は、フックを使用してtypescriptでコーディングしています。

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
このコードはOPの問題を解決する可能性がありますが、コードがOPの問題にどのように対処するかについての説明を含めるのが最善です。このようにして、将来の訪問者はあなたの投稿から学び、それを自分のコードに適用することができます。SOはコーディングサービスではなく、知識のリソースです。また、高品質で完全な回答が支持される可能性が高くなります。これらの機能は、すべての投稿が自己完結型であるという要件とともに、フォーラムとは異なるプラットフォームとしてのSOの強みの一部です。編集して情報を追加したり、ソースドキュメントで説明を補足したりできます。
ysf

1
更新され、もう少し説明しました。それが役に立てば幸い!
オエボラ

0

非常に簡単。以下のように()=> this.showCancel()に変更してください:

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

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

この例を確認する必要があります
。reactnativeで

0

私はボタンを非表示または表示するために以下の方法を使用しています。それがお役に立てば幸いです。ステータスを更新してCSSを隠すだけで十分です

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

実際、iOSの開発ではreact-native、私が使用したときdisplay: 'none'や以下のような場合:

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

iOSはonLoad、などの画像コンポーネントの他のものをロードしないため、以下のようなものを使用することにしました。

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

0

リアクションネイティブでコンポーネントを表示または非表示にする唯一の方法は、stateまたはのようなアプリの状態のパラメーターの値をチェックすることですprops。私は以下の完全な例を提供しました:

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;

これが結果です


0

それを非表示にしたいがvisibility: hidden、コンポーネントのスタイルのcssの設定のようにコンポーネントが占めるスペースを維持するopacity: 0場合は、トリックを実行する必要があります。

コンポーネントによっては、非表示のアイテムとの対話が可能なため、機能を無効にする他の手順が必要になる場合があります。


0

コンポーネントの表示と非表示の条件を使用できます

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

);
}

それで全部です。コーディングをお楽しみください...

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.