title: Expand/Collapse Logic for FlatList items - React Native
body: <p>React Native App with a simple FlatList.<br/>
  Requirement: Dropdown arrow icon needs to be displayed only when message is more than 3 lines. Short messages will not have any arrow icon.</p>
  <p><a href="https://i.stack.imgur.com/4lWoS.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/4lWoS.png" alt="enter image description here" /></a></p>
  <p>Current Logic - I am displaying the message with &quot;opacity:0&quot;, then finding the number of lines using onTextLayout, then checking if number of lines is greater than 3. <br/>
  If number of lines is greater than 3, a state is set and arrow icon is displayed for that message.</p>
  <pre class="lang-js prettyprint-override"><code>class FlatListItem extends Component {
    constructor(props) {
      super(props);
      this.state = {
        arrowClicked: false,
        length: false
      }
    }
    
    setFullLength(bool){
      this.setState({
        arrowClicked: !this.state.arrowClicked
      })
    }
      
    measureView(event, lines) {
      const line = event.nativeEvent.lines.length
      if (line &gt; 3) {
        this.setState({ length: true})
      }
    }
  
    render() {
      return (
        &lt;View style={textContainer}&gt;
          &lt;View style={{opacity:0, height:0}}&gt; 
            &lt;Text onTextLayout={(event, lines) =&gt; this.measureView(event, lines)}&gt;{message}&lt;/Text&gt;
          &lt;/View&gt;
          
          { arrowClicked === true ? (
              &lt;Text&gt;{message}&lt;/Text&gt;
            ) : (
              &lt;Text numberOfLines={3} onTextLayout={(event, lines) =&gt; this.measureView(event, lines)}&gt;{message}&lt;/Text&gt;
            )
          }
  
          &lt;View style={{flexDirection: 'row',alignItems: 'center',justifyContent: 'space-between'}}&gt;
            &lt;View style={{width:200}}&gt;
              &lt;Text&gt;{timestampToStr(createDate)}&lt;/Text&gt;         
            &lt;/View&gt;
            &lt;View style={{position:'absolute', right:3}}&gt;
              { length === true ? arrowClicked === true ? (
                  &lt;Icon type='materialicons' name='arrow-drop-up' size={33} onPress={()=&gt;{this.setFullLength()}}  /&gt;
                ) : (
                  &lt;Icon type='materialicons' name='arrow-drop-down' size={33} onPress={()=&gt;{this.setFullLength()}}  /&gt;
                ) : null
              }  
            &lt;/View&gt;
          &lt;/View&gt;
        )
      }
    }
  }
  </code></pre>
  <p>Setting a component with &quot;opacity:0&quot; is not the correct way!!! How else can I get the number of lines?? Is there any other way I can implement this??? Please help.</p>
  <p><strong>Updated Code:</strong><br/><br/>
  The below component  is my renderItem of FlatList<br/></p>
  <pre><code>
  renderItem({item}) {
      return &lt; FlatListItem item={item} onPress={() =&gt; {this.goToDetails(item)} /&gt;
    }
  
  
  &lt;FlatList
          ListFooterComponent={&lt;View style={{ paddingBottom: 50 }}&gt;&lt;/View&gt;}
          data={notifications}
          keyExtractor={(item) =&gt; item.id}
          renderItem={this.renderItem.bind(this)}
          refreshControl={this.refreshControl()}
           /&gt;
  
  </code></pre>
  <pre><code>class FlatListItem extends Component {
    constructor(props) {
      super(props);
      this.state = {
         max: [],
       num: []
      }
    }
  
    measureView(event, lines) {
        let { num } = this.state;
        num[index] = event.nativeEvent.lines.length;
        console.log(num[index])
        this.setState({ num });
    }
  
    setlenth = (index) =&gt; {
      let { max } = this.state;
      max[index] = this.state.num[index];
      this.setState({ max });
  }
  
  
  setNumberOfLines(e) {
    let { max } = this.state;
    max[index] = 3;
    this.setState({ max });
  }
  
  
  
    render() {
      return (
       &lt;View style={textContainer} onLayout={(e)=&gt;this.setNumberOfLines(e)}&gt;
                
          &lt;Text numberOfLines={this.state.max[index]} onTextLayout={(event, lines) =&gt; this.measureView(event, lines)} style={[subTitle,{fontSize:normalizeFontSize(15),lineHeight:normalizeLineHeight(15)}]}&gt;{alert}&lt;/Text&gt;
                
            
         &lt;View style={{position:'absolute', right:3}}&gt;
  
                {this.state.num[index] &gt; 3 ?
                              &lt;TouchableOpacity style={{ backgroundColor: 'red', height: 30, width: 30,justifyContent:'center',alignItems:'center' }} onPress={() =&gt; this.setlenth(index)}&gt;
                                  &lt;Icon name=&quot;arrow-drop-down&quot; /&gt;
                              &lt;/TouchableOpacity&gt;
                              :
                              null
                          }
                &lt;/View&gt; 
    
  }
  
  }
  
  </code></pre>