React-native-collapsible: Can we override renderHeader's onPress event?

Created on 27 Apr 2018  路  2Comments  路  Source: oblador/react-native-collapsible

I want to press header,dispatch an action to get panel's content.However, I found when I override onPress func in renderHeader, the Accordion is not collapsible any more. Here is my code:

 getReply = (id, isActive) => {
    if (!isActive) {
      this.setState({
        replyId: id,
      });
      this.props.dispatchGetReply(id); // dispatch action to get reply for panel header
      return null;
    }
    return null;
  };
  renderPanelHeader = (section, index, isActive) => {
    const src = isActive ? imgSource.arrow_down : imgSource.arrow_right;
    return (
      <View style={styles.pannelHeader}>
        <TouchableOpacity style={{ flex: 1 }} onPress={() => this.getReply(section.id, isActive, section)}>
          <View style={{ flex: 1 }}>
            <View style={styles.pannelTitle}>
              <LText style={styles.pannelTitleText}>{feedback_type[section.type]}</LText>
              <Image source={src} style={styles.pannelTitleIcon} resizeMode='contain' />
            </View>
            <View style={styles.pannelStatus}>
              <LText style={styles.pannelStatusContent}>{section.content}</LText>
              <LText style={[section.status === 0 ? styles.statusPending : styles.statusResolve]}>
                {feedback_status[section.status]}
              </LText>
            </View>
            <LText style={styles.pannelTime}>{section.created_at}</LText>
          </View>
        </TouchableOpacity>
      </View>
    );
  };

can you expose an property to control the state of collapsible?

help wanted awaiting-reply

Most helpful comment

@iRoachie Hey,thanks for your help, it now works great! BTW,here is my code,hope that can help others

 state = {
    replyId: null,
    activeSection: null, // 'null' means no section is expanded  at initial
  };

  onChange = (index) => {
    console.log('section onChange', index);
    if (index !== false) { // expand section
      // use pressed section index to find the section id
      const { id } = this.props.data.feedbacks[index];
      this.props.dispatchGetReply(id);
      // then set state to expand the section you pressed
      this.setState({
        activeSection: index,
        replyId: id,
      });
      console.log('id', id);
    } else {
      this.setState({
        activeSection: null,
      });
      return null;
    };
  };

// here is Accordion
<Accordion
      sections={this.props.data.feedbacks}
      underlayColor='transparent'
      renderHeader={this.renderPanelHeader}
      renderContent={this.renderPannelContent}
      onChange={this.onChange}
      activeSection={this.state.activeSection}
/>

thanks again for the great libaray!

All 2 comments

There's no need to have a touchable inside the header. Instead you can use the onChange prop along with the activeSection prop to handle the closing and opening yourself.

Your onChange could simply have a function that does the getReply logic you have above, then set the state whenever your logic is complete.

state = {
  activeSection: 0
}

onChange = (section) => {
 // Do logic in here 
 // then set the state to toggle the section
} 

render() {
  return (
    <Accordion onChange={this.onChange} activeSection={this.state.activeSection} />
  )
}

@iRoachie Hey,thanks for your help, it now works great! BTW,here is my code,hope that can help others

 state = {
    replyId: null,
    activeSection: null, // 'null' means no section is expanded  at initial
  };

  onChange = (index) => {
    console.log('section onChange', index);
    if (index !== false) { // expand section
      // use pressed section index to find the section id
      const { id } = this.props.data.feedbacks[index];
      this.props.dispatchGetReply(id);
      // then set state to expand the section you pressed
      this.setState({
        activeSection: index,
        replyId: id,
      });
      console.log('id', id);
    } else {
      this.setState({
        activeSection: null,
      });
      return null;
    };
  };

// here is Accordion
<Accordion
      sections={this.props.data.feedbacks}
      underlayColor='transparent'
      renderHeader={this.renderPanelHeader}
      renderContent={this.renderPannelContent}
      onChange={this.onChange}
      activeSection={this.state.activeSection}
/>

thanks again for the great libaray!

Was this page helpful?
0 / 5 - 0 ratings