1

I know how to add and remove a single component by changing the state. But this way wont work if you have multiple components to remove. For instance lets say I have 3 Views. How can I remove them when I click on them.

Example code:

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(){

    }
}

Another example will be when I have a ListView with buttons inside. These are buttons to invite a user. When I click on the button I want to hide the button for that specific row in the ListView.

Any suggestions?

2 Answers 2

4

Thanks to Giorgos I found a solution for my own question. I created a separate component with a hide function inside the component. Now I can just add this component anywhere in a view or in a listView and when I click on it it will hide. Remember this only hides the component and does not unmount it.

This is just an example so I created a button component.

My Button Component:

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

In my View I just render my Component:

 render() {
    return (
      <View style={styles.container}>
        <ButtonComponent/>
        <ButtonComponent/>
        <ButtonComponent/>
      </View>
    );
  }
Sign up to request clarification or add additional context in comments.

2 Comments

That's a good approach -allows you to reuse your button without extra code. I'm glad that I've helped.
Add else { return null; } inside renderButtonComponent() otherwise you will get an error that this function returned nothing.
2
+50

You have to use your component's state. Whenever you call setState the component's render() function is triggered again. There based on what the current state is, you can decide what to show and what not. For example:

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

In the above example, you render your view based on the current state. When the button is clicked, you update the state by calling setState() which, like I mentioned before, will trigger another call to render().

With the ListView the approach is the same but the implementation slightly different. What you need to do there is to save your list of items in the state of your component and whenever you want to add/remove an item, you update the list accordingly and then update the state using setState. For example, something similar to this:

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

Hope this helps.

3 Comments

thanks for answering. But what if I render 100 views? (I won't be creating 100 this is for example purposes) Does this means I need to create 100 state objects to handle all 100? Let's say I'm not using views. What if I create a button component and I want to remove my button component when I click on it? I would I do something like that?
If you render 100 views, then I assume that you render them inside a ListView so the second example that I gave above should be your guide. Regarding the button, yes, it would also be the same logic. Keep in mind that in React Native, unlike native Android and iOS, you cannot simply hide and show views. You have to either render them or not. And the way to trigger a new render() is by using setState(). Let me know if you have further questions.
The ListView way wouldn't have worked the way I needed to do it. But I found what I wanted to achieve. I posted my answer. I'm still awarding you the bounty but can only do it in 18 hours. Thanks for the help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.