Jonis Maurin Ceara
Jonis Maurin Ceara

Reputation: 165

How to close swipe item in react-native?

I have this code (get from native-base example) that is working fine. But after click on either sides (right or left), the 'swipe' still open. I know that there is a method called closeRow(), but I don't know how to apply in this case. Left button is for 'split' item into 2 or more, while right button is to delete current item. What I need is to close all opened rows in this list. Why all? Because in the case of 'delete' function, the current item is deleted in the right way, but the next-one get right button opened (since it's the same 'index' of list, even if the item itself is different). This is my current code:

<Container style={styles.container}>
        <Header>
          <Left>
            <Button transparent onPress={() => this.props.navigation.goBack()}>
              <Icon name="arrow-back" />
            </Button>
          </Left>
          <Body>
            <Title>{translate("title", { ...i18n_opt, name })}</Title>
          </Body>
        </Header>

        <Content>
          <Modal
            isVisible={this.state.visibleModal === true}
            animationIn={"slideInLeft"}
            animationOut={"slideOutRight"}
          >
            {this._renderModalContent()}
          </Modal>

          <View style={styles.line}>
            <View style={{ flex: 2 }}>
              <Text style={[styles.alignCen, styles.headerTitle]}>
                {translate("lap", { ...i18n_opt })}
              </Text>
            </View>
            <View style={{ flex: 10 }}>
              <Text style={[styles.alignCen, styles.headerTitle]}>
                {translate("time", { ...i18n_opt })}
              </Text>
            </View>
            <View style={{ flex: 3 }}>
              <Text
                style={[
                  { paddingRight: 10 },
                  styles.alignRig,
                  styles.headerTitle
                ]}
              >
                {translate("diff", { ...i18n_opt })}
              </Text>
            </View>
          </View>

          <List
            enableEmptySections
            dataSource={laps2}
            ref={c => {
              this.component = c;
            }}
            renderRow={data => <PersonalRankItem dados={data} />}
            renderLeftHiddenRow={data => (
              <Button
                full
                onPress={() => {
                  this.setState({
                    ...this.state,
                    visibleModal: true,
                    cur_tx_id: tx_id,
                    cur_lap: data.lap
                  });
                }}
                style={{
                  backgroundColor: "#CCC",
                  flex: 1,
                  alignItems: "center",
                  justifyContent: "center",
                  marginBottom: 6
                }}
              >
                <MaterialCommunityIcons
                  name="arrow-split-vertical"
                  size={20}
                  color="#5e69d9"
                />
              </Button>
            )}
            renderRightHiddenRow={(data, secId, rowId, rowMap) => (
              <Button
                full
                danger
                onPress={_ => {
                  //alert("Delete");
                  //console.log("Data.lap:",data.lap);
                  dispatchDeleteLap(tx_id, data.lap, true);
                }}
                style={{
                  flex: 1,
                  alignItems: "center",
                  justifyContent: "center",
                  marginBottom: 6
                }}
              >
                <Icon active name="trash" size={20} />
              </Button>
            )}
            leftOpenValue={70}
            rightOpenValue={-70}
          />
        </Content>
      </Container>

Upvotes: 2

Views: 6098

Answers (1)

I Putu Yoga Permana
I Putu Yoga Permana

Reputation: 4220

Goal

You need to close all the rows, each time one of row side button clicked. The next problem is when item deleted, the next row is opened even the content is different.

How?

All you need is first, collect the ref of each rows and then when the button clicked, trigger the closeRow method of all ref's row. And the important part, make your row key persistent and unique to avoid problem like in your case.

Quick Code Sample

class Screen extends Component {
  constructor(props) {
    super(props);
    this._rowRefs = [];
  }

  // this is used to collect row ref
  collectRowRefs = (ref) => {
    this._rowRefs.push(ref);
  };

  // your render row function
  renderRow = (data) => (
    // make this row key consistent and unique like Id, do not use index counter as key
    <PersonalRankItem key={data.id} dados={data} ref={this.collectRowRefs}/>  
  );

  // When your hidden side button is clicked
  onButtonClicked = (data) => {
    // do the button normal action
    // ....

    // close each row
    this._rowRefs.forEach((ref) => {
      ref.closeRow();
    });
  };

  // this is your hidden side button
  renderLeftHiddenRow = () => (
    <Button onClick={this.onButtonClicked} />
  );

  render() {
    // Your List in here
    return (
      <List
        renderRow={this.renderRow}
        renderLeftHiddenRow={this.renderLeftHiddenRow}
      />
    )
  }
}

Upvotes: 1

Related Questions