Ẩn / Hiển thị các thành phần trong phản ứng gốc


143

Tôi thực sự mới với React Native và tôi tự hỏi làm thế nào tôi có thể ẩn / hiển thị một thành phần.
Đây là trường hợp thử nghiệm của tôi:

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

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

Tôi có một TextInputthành phần, điều tôi muốn là hiển thị TouchableHighlightkhi đầu vào lấy tiêu điểm, sau đó ẩn TouchableHighlightkhi người dùng nhấn nút hủy.

Tôi không biết cách "truy cập" TouchableHighlightthành phần này để ẩn / hiển thị nó bên trong các chức năng của mình showCancel/hideCancel.
Ngoài ra, làm thế nào tôi có thể ẩn nút ngay từ đầu?


Câu trả lời:


135

Tôi sẽ làm một cái gì đó như thế này:

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
Cảm ơn bạn rất nhiều vì điều này, chỉ một thay đổi nhỏ mà tôi cần thực hiện: onF Focus = {() => this.showftime ()} đây cần phải là một hàm gọi lại.
Crysfel

3
Chỉ làm việc cho tôi sau khi thay đổi return ''thànhreturn null
k7k0

33
Bạn cũng có thể làm {someBoolVal && <Component />}và nó sẽ chỉ hiển thị nếu giá trị bool là true.
Nathan Hyland

Đây là câu trả lời hay nhất
Kirill Gusyatin

3
Tôi không biết đây là câu trả lời được chấp nhận không thực hiện hiển thị / ẩn chức năng mong muốn ban đầu, nhưng thay vào đó thêm / xóa
Muhammad Aref

150

Trong chức năng kết xuất của bạn:

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

Sau đó, chỉ cần làm:

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

2
Điều này làm việc cho tôi. Tuy nhiên, tôi không chắc tại sao khi tôi làm một cái gì đó như { this.state.showTheThing && (<Text>foo</Text> && <Text>bar</Text>)}chỉ "thanh" được hiển thị trong giao diện người dùng. Tôi hy vọng "foo" và "bar" sẽ được hiển thị. Những gì tôi cần làm để giải quyết vấn đề này là gọi{ this.state.showTheThing && (<Text>foo</Text>} { this.state.showTheThing && (<Text>bar</Text>}
tonatiuhnb

2
có lẽ điều này làm việc? bởi vì logic &&không kết hợp các yếu tố{ this.state.showTheThing && (<View><Text>foo</Text><Text>bar</Text></View>)}
muescha

Điều này làm việc cho tôi, tôi muốn hiển thị nút "Bước tiếp theo" khi người dùng tải lên cấu hình của họ. vì vậy mã của tôi là:{this.state.hasPic && <Button title="Go to next step" onPress={this._nextStep} />}
Daggie Blanqx - Douglas Mwangi

Đối với bất kỳ ai đang vật lộn với việc hiển thị nhiều hơn một thành phần, hãy bọc thành phần của bạn bằng một đoạn. ví dụ. <React.Fragment><Text>Foo</Text><Text>Bar></Text></React.Fragment>
Ben Cull

48

Trong phản ứng hoặc phản ứng tự nhiên, cách ẩn / hiển thị thành phần hoặc thêm / xóa không hoạt động như trong Android hoặc iOS. Hầu hết chúng ta nghĩ rằng sẽ có chiến lược tương tự như

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

Nhưng cách phản ứng công việc bản địa là hoàn toàn khác nhau. Cách duy nhất để đạt được loại chức năng này là đưa thành phần của bạn vào DOM hoặc xóa khỏi DOM.

Ở đây trong ví dụ này tôi sẽ thiết lập khả năng hiển thị của chế độ xem văn bản dựa trên nút bấm.

nhập mô tả hình ảnh ở đây

Ý tưởng đằng sau tác vụ này là tạo một biến trạng thái được gọi là trạng thái có giá trị ban đầu được đặt thành false khi sự kiện nhấn nút xảy ra sau đó giá trị bật. Bây giờ chúng ta sẽ sử dụng biến trạng thái này trong quá trình tạo thành phần.

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

điều duy nhất cần chú ý trong đoạn mã này là renderIfđây thực sự là một hàm sẽ trả về thành phần được truyền cho nó dựa trên giá trị boolean được truyền cho nó.

renderIf(predicate)(element)

renderif.js

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

Thông minh :) trường hợp sử dụng cho thunk là gì?
goldylucks

Haha. Xuất sắc!
Jaseem Abbas

Giải pháp này có ý nghĩa đối với các trường hợp sử dụng trong đó hộp thoại chỉ cần hiển thị khi cần. Ty!
SoundStage

2
Điều này sẽ không hoạt động nếu bạn cần giữ trạng thái, xóa phần tử thiết lập lại trạng thái của mình. vì vậy mỗi lần bạn kết xuất lại giống như bạn tạo lại thành phần.
Daniel Jose Padilla Peña


20

trong render () bạn có thể hiển thị một cách có điều kiện JSX hoặc trả về null như trong:

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

3
Cần phải có dấu ngoặc đơn trong dòng 2.
jiexishede

Cảm ơn bạn vì giải pháp đơn giản nhất
Sam

13

Tôi cần phải chuyển đổi giữa hai hình ảnh. Với chuyển đổi có điều kiện giữa chúng, có độ trễ 5sec không có hình ảnh hiển thị.

Tôi đang sử dụng phương pháp tiếp cận từ câu trả lời của amos. Đăng dưới dạng câu trả lời mới vì thật khó để đưa mã vào bình luận với định dạng phù hợp.

Chức năng kết xuất:

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

Kiểu dáng:

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

screencast


Điều này giữ cho các thành phần trong bộ nhớ, có thể là một vấn đề với các thành phần lớn. Tại sao không sử dụng các ví dụ tuyệt vời ở trên? Họ sẽ chèn đúng ảnh và xóa hoàn toàn ảnh khác ...
NHƯ

4
bất kỳ ví dụ nào trong số đó không hoạt động chính xác khi bạn cố gắng tạo spinner hoạt hình. Giống như tôi đã đề cập trong câu trả lời của mình trên Android khi cố gắng chuyển img cho gif hoạt hình, sẽ gây ra độ trễ 5s khi không hiển thị png cũng như gif. Tôi tin rằng sự chậm trễ là do tải gif vào bộ nhớ, có thể mất một chút thời gian. Tuy nhiên, iOS dường như làm công việc tốt hơn nhiều ở đây. Nếu bạn không tin tôi, hãy tự mình thử.
mauron85

1
Tất nhiên như đã chỉ ra nó không phải là giải pháp tối ưu cho mọi thành phần. Nhưng IMHO để tải spinner thì nó vẫn ổn. Cuối cùng nó sẽ được tải khi người dùng chuyển sang trang khác.
mauron85

13

Hầu hết thời gian tôi đang làm một cái gì đó như thế này:

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

Nếu bạn chưa quen với lập trình, dòng này phải lạ đối với bạn:

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

Dòng này tương đương với

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

Nhưng bạn không thể viết một điều kiện if / other trong nội dung JSX (ví dụ: phần return () của hàm kết xuất) để bạn sẽ phải sử dụng ký hiệu này.

Thủ thuật nhỏ này có thể rất hữu ích trong nhiều trường hợp và tôi khuyên bạn nên sử dụng nó trong quá trình phát triển của mình vì bạn có thể nhanh chóng kiểm tra một điều kiện.

Trân trọng,


Bạn có thể giải thích rõ hơn về cách bạn xác định <ToHideAndShowComponent />
Ritveak

12

nhập mô tả hình ảnh ở đây

Ẩnhiển thị chế độ xem của phụ huynhActivity Indicator

constructor(props) {
  super(props)

  this.state = {
    isHidden: false
  }  
} 

Ẩnhiển thị như sau

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

Tham khảo đầy đủ

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

Nhấn nút nhấn đặt trạng thái như sau

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

Khi bạn cần ẩn

this.setState({isHidden: false})

11

Bố cục của React Native có displayhỗ trợ thuộc tính, tương tự như CSS. Các giá trị có thể: noneflex(mặc định). https://facebook.github.io/react-native/docs/layout-props#display

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

2
Cẩn thận không sử dụng cái này với position: absolute, nó không thực sự che giấu nó! Lỗi đã biết từ 0,54 - 0,59 (ít nhất): github.com/facebook/react-native/issues/18415
Joshua Pinter

10

chỉ dùng

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

4
Sẽ rất hữu ích nếu bạn thêm một số bối cảnh / chi tiết vào câu trả lời.
UditS

Giả sử bạn có một cơ chế để quyết định thành phần nào cần ẩn, câu trả lời này khá hữu ích. Bạn có thể bao bọc bất kỳ thành phần nào bạn đang cố ẩn bằng Chế độ xem với style = {{width: 0, height: 0}}.
Josh Baker

6
Làm thế nào để bạn khôi phục phần tử về chiều rộng và chiều cao ban đầu?
Một số Juan

4
không hiểu tại sao điều này bị hạ thấp, nhưng trong nhiều trường hợp, đó là lời khuyên tốt. Tôi cần phải chuyển đổi giữa gif hoạt hình và không hoạt hình. Chuyển đổi có điều kiện img gây ra sự chậm trễ không có img trên màn hình. Là một phần của sửa lỗi, tôi đang hiển thị cả img, nhưng cái cần ẩn có chiều rộng và chiều cao bằng không.
mauron85

Điều này giữ cho thành phần trong bộ nhớ, có thể là một vấn đề với các thành phần lớn. Tại sao không sử dụng các ví dụ tuyệt vời ở trên? Họ chèn và xóa hoàn toàn thành phần ...
NHƯ

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

tuyên bố hiển thị sai vì vậy theo chế độ / chế độ xem mặc định được ẩn

ví dụ = () => {

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

}

** Chức năng gọi **

{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

Tôi có cùng một vấn đề khi tôi muốn hiển thị / ẩn Chế độ xem, nhưng tôi thực sự không muốn giao diện người dùng nhảy xung quanh khi mọi thứ được thêm / xóa hoặc nhất thiết phải xử lý kết xuất lại.

Tôi đã viết một Thành phần đơn giản để đối phó với nó. Hoạt hình theo mặc định, nhưng dễ dàng để chuyển đổi. Tôi đặt nó trên GitHubNPM với một readme, nhưng tất cả các mã dưới đây.

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;

Một thứ tuyệt vời, đúng như những gì tôi đang tìm kiếm :)
Adamski

Điều này hoạt động tốt nhất và hoạt động như một chế độ xem phù hợp khi bạn đặt các thành phần khác có vòng đời bên trong chế độ xem (không hoạt động với visible && (...).
dB.

6

Một tùy chọn bổ sung là áp dụng định vị tuyệt đối thông qua kiểu dáng , đặt thành phần ẩn trong tọa độ ngoài màn hình:

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

Không giống như trong một số đề xuất trước đây, điều này sẽ ẩn thành phần của bạn khỏi chế độ xem NHƯNG cũng sẽ hiển thị nó (giữ nó trong DOM), do đó làm cho nó thực sự vô hình .


2
Ý tưởng này phù hợp với tôi, cảm ơn. Nếu có ai cần, hãy xem nó: gist.github.com/jaysoo/cbb81a07cc22015a72e9
Chaki_Black

3

Nếu bạn cần thành phần vẫn được tải nhưng ẩn, bạn có thể đặt độ mờ thành 0. (ví dụ tôi cần điều này cho máy ảnh expo)

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

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

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


2

Ví dụ sau đây là mã hóa trong bản thảo với Móc.

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
Mặc dù mã này có thể giải quyết vấn đề của OP, tốt nhất là bao gồm một lời giải thích về cách mã của bạn giải quyết vấn đề của OP. Theo cách này, khách truy cập trong tương lai có thể học hỏi từ bài đăng của bạn và áp dụng nó vào mã của riêng họ. SO không phải là một dịch vụ mã hóa, mà là một nguồn tài nguyên cho kiến ​​thức. Ngoài ra, chất lượng cao, câu trả lời đầy đủ có nhiều khả năng được nâng cao. Các tính năng này, cùng với yêu cầu tất cả các bài đăng đều khép kín, là một số điểm mạnh của SO như một nền tảng, phân biệt nó với các diễn đàn. Bạn có thể chỉnh sửa để thêm thông tin bổ sung & / hoặc để bổ sung giải thích của bạn với tài liệu nguồn.
ysf

1
Cập nhật, giải thích thêm một chút. Hy vọng nó giúp!
Oyebola


0

tôi chỉ sử dụng phương pháp dưới đây để ẩn hoặc xem một nút. hy vọng nó sẽ giúp bạn chỉ cần cập nhật trạng thái và thêm ẩn css là đủ cho tôi

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

Trên thực tế, trong quá trình phát triển iOS, react-nativekhi tôi sử dụng display: 'none'hoặc đại loại như dưới đây:

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

IOS không tải bất cứ thứ gì khác của thành phần Image như onLoad, v.v., vì vậy tôi quyết định sử dụng một cái gì đó như dưới đây:

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

0

Cách duy nhất để hiển thị hoặc ẩn một thành phần trong phản ứng gốc là kiểm tra giá trị của một tham số của trạng thái ứng dụng như statehoặc props. Tôi đã cung cấp một ví dụ đầy đủ như dưới đây:

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;

Đây là kết quả


0

Nếu bạn muốn ẩn nó nhưng giữ không gian bị chiếm bởi thành phần như visibility: hiddencài đặt của css theo kiểu của thành phần opacity: 0thì nên thực hiện thủ thuật.

Tùy thuộc vào thành phần, các bước khác trong việc vô hiệu hóa chức năng có thể được yêu cầu vì có thể tương tác với một vật phẩm vô hình.


0

Bạn có thể sử dụng các điều kiện để hiển thị và ẩn các thành phần

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

);
}

đó là tất cả. thưởng thức mã hóa của bạn ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.