繁体   English   中英

在本机反应中隐藏/显示组件

[英]Hide/Show components in react native

我对 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中隐藏/显示它。
另外,如何从一开始就隐藏按钮?

在您的渲染功能中:

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

然后做:

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

我会做这样的事情:

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

});

在 react 或 react native 中,组件隐藏/显示或添加/删除的方式不像在 android 或 iOS 中那样工作。 我们大多数人认为会有类似的策略,比如

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

但是反应原生工作的方式完全不同。 实现这种功能的唯一方法是将组件包含在 DOM 中或从 DOM 中删除。

在此示例中,我将根据按钮单击设置文本视图的可见性。

在此处输入图像描述

这个任务背后的想法是创建一个名为 state 的状态变量,当按钮点击事件发生时,它的初始值设置为 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)

渲染.js

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

React Native 的布局有display属性支持,类似于 CSS。 可能的值: noneflex (默认)。 https://facebook.github.io/react-native/docs/layout-props#display

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

在 render() 中,您可以有条件地显示 JSX 或返回 null,如下所示:

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

大多数时候我都在做这样的事情:

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() 部分),因此您必须使用这种表示法。

这个小技巧在很多情况下都非常有用,我建议你在开发中使用它,因为你可以快速检查一个条件。

问候,

编辑:对于更直接的合成器,您可以执行{this.state.isHidden && <ToHideAndShowComponent/>} 这里,左边的操作数在右边的操作数之前被评估,所以如果isHidden为假,那么组件将不会显示。

只需使用

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

我需要在两个图像之间切换。 在它们之间进行有条件的切换时,有 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,
  },
});

截屏

在此处输入图像描述

隐藏显示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>
   );
}

On Button 按下设置状态如下

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

当你需要隐藏

this.setState({isHidden: false})

我有同样的问题,我想显示/隐藏视图,但我真的不希望 UI 在添加/删除内容或必须处理重新渲染时跳来跳去。

我写了一个简单的组件来为我处理它。 默认动画,但易于切换。 我用自述文件将它放在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;

另一个选项是通过样式应用绝对定位,将隐藏组件设置为屏幕外坐标:

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

与之前的一些建议不同,这会将您的组件从视图中隐藏,但也会呈现它(将其保留在 DOM 中),从而使其真正不可见

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

如果您需要组件保持加载但隐藏,您可以将不透明度设置为 0。(例如,我需要这个用于展览相机)

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

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

//when you want to hide
this.setState({opacity: 0})
// 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)}}/>

您可以使用我的模块react-native-display来显示/隐藏组件。

以下示例是使用 Hooks 在 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>
  ......

}

如果您不想从页面中删除组件,例如隐藏 WebView,我会保证使用 opacity-method。

<WebView
   style={{opacity: 0}} // Hide component
   source={{uri: 'https://www.google.com/'}}
 />

如果您需要向 3rd 方网站提交表单,这将非常有用。

显示\隐藏组件的三种方式:

- 类组件:/ --------------------------------- -------------------------------------------------- -------------

在我使用以下状态的所有示例中:

.  
...
constructor(props) {
super(props);
this.state = {showComponent: true};
}

1.使用display道具

<View display={this.state.showComponent ? 'flex' : 'none'} /> 

2.使用带styledisplay道具

<View style={{display:this.state.showComponent ? 'flex' : 'none'}} />

3.限制渲染

{
    this.state.showComponent &&
    <View /> // Or <View> ... </View>
}


- 功能组件:/ --------------------------------------------- -------------------------------------------------- -------------

在我使用以下状态的所有示例中:

const [showComponent, setShowComponent] = useState(true);

1.使用display道具

<View display={showComponent ? 'flex' : 'none'} /> 

2.使用带styledisplay道具

<View style={{showComponent  ? 'flex' : 'none'}} />

3.限制渲染

{
    showComponent &&
    <View /> // Or <View> ... </View>
}

我通常使用这样的东西

const [showComponent, setShowComponent] = useState(false)
return(
    <div>
         {showComponent && (<Text>Hello</Text>)}
         <Button onPress={() => {setShowComponent(true)}}>Click me</Button>
    </div>
)

一旦按下按钮,它将显示“你好”。 这称为条件渲染。 您可以参考w3schools了解条件渲染。

我只是使用下面的方法来隐藏或查看按钮。 希望它会帮助你。 只需更新状态并添加隐藏 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>)
}

实际上,在我使用display: 'none'或类似下面的东西时,在react-native的 iOS 开发中:

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

iOS 不会加载 Image 组件的任何其他内容,例如onLoad等,因此我决定使用以下内容:

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

如果您想隐藏它,但要保持组件占用的空间,例如 css 的visibility: hidden设置opacity: 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>

在 react native 中显示或隐藏组件的唯一方法是检查应用状态参数的值,例如stateprops 我提供了一个完整的示例,如下所示:

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;

这是结果

您可以使用条件来显示和隐藏组件

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

我这样解决这个问题:

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

只需简单地使用它,因为我想使用“useRef”条件不是我的选择。 当你想使用 useRef 钩子并按下按钮时,你可以使用这个假设。

   <Button
      ref={uploadbtn}
      buttonStyle={{ width: 0, height: 0, opacity: 0, display: "none" }}
      onPress={pickImage}
    />

我们现在有钩子,所以我建议重新格式化。 使用挂钩打开/关闭组件。

const [modalVisible, setModalVisible] = setState(false);

然后有一个按钮

<Button title="Press Me" onPress={() => {
   setModalVisible(true);
}}

然后,在您的退货声明中

return(
<View>
    {modalVisible &&
   Insert modal code in here.
}
</View>
)

你可以做到,使用 useState Hook

The useState basically, is a feature which helps us preserve the values of variables even after multiple re-renders.

它充当本地 state 管理工具,用于在组件渲染或重新渲染后存储值。

此外,您还可以通过更改 state 变量的值来触发它来更新 UI。

const [show,setShow] = useState(true)

所以,这里我们解构了useState发送的值,第一个是变量,通过它我们可以得到值,第二个是一个function,通过它我们可以更新state变量值。

所以,在你的情况下 -

import React, {useState} from 'react';
import { Text, View, StyleSheet,Button } from 'react-native';
import Constants from 'expo-constants';

export default function App() {
const [show,setShow] = useState(true)
return (
 <View style={styles.container}>
   {show && <Text style={styles.paragraph}>
     Showing and Hiding using useState
   </Text>}
    <Button
     title="Press me"
     onPress={() => {setShow(!show)}}
   />
 </View>
);
}

const styles = StyleSheet.create({
container: {
 flex: 1,
 justifyContent: 'center',
 paddingTop: Constants.statusBarHeight,
 backgroundColor: '#ecf0f1',
 padding: 8,
},
paragraph: {
 margin: 24,
 fontSize: 18,
 fontWeight: 'bold',
 textAlign: 'center',
},
});

在此示例中,按下按钮时,我们将 state 变量从 true 切换为 false。

您可以使用 boolean 条件显示或隐藏 JSX 代码,我们在此语句中执行此操作。

{show && <Text style={styles.paragraph}>
     Showing and Hiding using useState
   </Text>}

这是使用 state 进行 UI 操作的一种快速有效的方法。

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

);
}

就这样。 享受你的编码...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM