【问题标题】:Remove multiple components in react native移除 react native 中的多个组件
【发布时间】:2023-04-04 08:20:01
【问题描述】:

我知道如何通过更改状态来添加和删除单个组件。但是,如果您要删除多个组件,这种方式将不起作用。例如,假设我有 3 个视图。当我点击它们时如何删除它们。

示例代码:

class Example extends Component {
    render(){
        return (
          <View>
            <View>
              <TouchAbleOpacity onPress={() => this.removeView()}>
                <Text>Remove View 1</Text>
              </TouchAbleOpacity>
            </View>
            <View>
              <TouchAbleOpacity onPress={() => this.removeView()}>
                <Text>Remove View 2</Text>
              </TouchAbleOpacity>
            </View>
            <View>
              <TouchAbleOpacity onPress={() => this.removeView()}>
                <Text>Remove View 3</Text>
              </TouchAbleOpacity>
            </View>
          </View>
        )
    }

    removeView(){

    }
}

另一个例子是当我有一个带有按钮的 ListView 时。这些是邀请用户的按钮。当我单击按钮时,我想在 ListView 中隐藏该特定行的按钮。

有什么建议吗?

【问题讨论】:

    标签: android ios reactjs react-native


    【解决方案1】:

    感谢 Giorgos,我为自己的问题找到了解决方案。我在组件内部创建了一个带有隐藏功能的单独组件。现在我可以在视图或列表视图中的任何位置添加这个组件,当我点击它时它会隐藏。请记住,这只会隐藏组件而不会卸载它。

    这只是一个例子,所以我创建了一个按钮组件。

    我的按钮组件:

    class ButtonComponent extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          hide:false
        }
      }
    
      render() {
        return (
          <View style={styles.container}>
            {this.renderButtonComponent()}
          </View>
        );
      }
    
      renderButtonComponent(){
        if(!this.state.hide){
          return (
            <TouchableOpacity onPress={this.hide.bind(this)}>
                <Text>Button</Text>
            </TouchableOpacity>
          );
        }
      }
    
      hide(){
        this.setState({
          hide:true
        });
      }
    }
    

    在我的视图中,我只是渲染我的组件:

     render() {
        return (
          <View style={styles.container}>
            <ButtonComponent/>
            <ButtonComponent/>
            <ButtonComponent/>
          </View>
        );
      }
    

    【讨论】:

    • 这是一个很好的方法 - 允许您重复使用您的按钮而无需额外的代码。我很高兴能帮上忙。
    • renderButtonComponent()中添加else { return null; },否则你会得到一个错误,这个函数什么也没返回。
    【解决方案2】:

    您必须使用组件的状态。每当您调用setState 时,组件的render() 函数就会再次触发。根据当前状态,您可以决定显示什么,不显示什么。例如:

    class Example extends Component {
        constructor(props){
           // initialize state
           this.state = { 
                          isView1Visible: true, 
                          isView2Visible: true, 
                          isView2Visible: true 
                        }
        }
    
        render(){
            return (
              <View>
                { this.renderView1() }
                { this.renderView2() }
                { this.renderView3() }
              </View>
            )
        }
    
        renderView1(){
           if(this.state.isView1Visible){
                return (
                   <View>
                      <TouchAbleOpacity onPress={() => this.setState( {isView1Visible: false} )}>
                      <Text>Remove View 1</Text>
                      </TouchAbleOpacity>
                  </View>    
                )
        }
    
        renderView2(){
           if(this.state.isView2Visible){
                return (
                     ...   
                )
        }
    
        renderView3(){
           if(this.state.isView3Visible){
                return (
                     ...   
                )
        }
    }
    

    在上面的示例中,您根据当前状态渲染视图。单击按钮时,您通过调用 setState() 来更新状态,就像我之前提到的,这将触发对 render() 的另一个调用。

    ListView 的方法相同,但实现略有不同。您需要做的是将您的项目列表保存在组件的状态中,并且每当您想要添加/删除项目时,您相应地更新列表,然后使用setState 更新状态。例如,类似这样的:

      constructor(props) {
        super(props);
        var list = [ ... ]
        const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
        this.state = {
          dataSource: ds,
          items: ds.cloneWithRows(list)
        };
      }
    
      render() {
        return (
          <View>
            <ListView 
              dataSource={this.state.items}
              renderRow={(rowData) => this.renderRow(rowData) /> } />
          </View>
        )
      }
    
      renderRow(rowData) {
         <View>
             <TouchAbleOpacity onPress={() => this.updateList()}>
                 <Text>Remove View 1</Text>
             </TouchAbleOpacity>
         </View> 
      }    
    
      updateList() {
        // do some changes to your list and update the state.
        var newItems = ...
    
        this.setState({
          items: newItems
        })
      }
    

    希望这会有所帮助。

    【讨论】:

    • 感谢您的回答。但是如果我渲染 100 个视图呢? (我不会创建 100 个,这是出于示例目的)这是否意味着我需要创建 100 个状态对象来处理所有 100 个?假设我没有使用视图。如果我创建了一个按钮组件并且我想在单击它时删除我的按钮组件怎么办?我会做这样的事情吗?
    • 如果您渲染 100 个视图,那么我假设您在 ListView 内渲染它们,所以我上面给出的第二个示例应该是您的指南。关于按钮,是的,它也将是相同的逻辑。请记住,在 React Native 中,与原生 Android 和 iOS 不同,您不能简单地隐藏和显示视图。您必须渲染它们或不渲染它们。触发新render() 的方法是使用setState()。如果您还有其他问题,请告诉我。
    • ListView 方式不会像我需要的那样工作。但我找到了我想要实现的目标。我发布了我的答案。我仍在奖励你,但只能在 18 小时内完成。感谢您的帮助。
    猜你喜欢
    • 2015-07-26
    • 2018-12-02
    • 1970-01-01
    • 2020-01-06
    • 2016-10-07
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多