React-native-reanimated-bottom-sheet: Callback onClose

Created on 8 Jul 2019  路  11Comments  路  Source: osdnk/react-native-reanimated-bottom-sheet

I want to implement a close callback that listens to the bottom-sheet. How do I implement this?

Most helpful comment

@paranoia5 Hooks version:

const MyBottomSheet = (props: Props) => {
  const { onClose } = props
  const bottomSheetRef = useRef<BottomSheet | null>(null)
  const callbackNode = useRef(new Animated.Value(1))

  Animated.useCode(
    Animated.onChange(
      callbackNode.current,
      Animated.block([
        Animated.cond(
          Animated.greaterOrEq(callbackNode.current, 1),
          Animated.call([], () => {
            onClose && onClose()
          })
        ),
      ])
    ),
    [onClose]
  )

  return (
    <React.Fragment>
      <BottomSheet
        ref={bottomSheetRef}
        callbackNode={callbackNode.current}
        initialSnap={0}
        snapPoints={[0, MODAL_HEIGHT]}
        renderHeader={...}
        renderContent={...}
      />
    </React.Fragment>
  )
}

All 11 comments

You can combine Animated.Code component with callbackNode property e.g.

class MySheet extends React.Component {
  bottomSheetRef = React.createRef()
  callbackNode = React.createRef()

  render() {
    return (
      <React.Fragment>
        {this.callbackNode.current && (
          <Animated.Code>
            {() => Animated.call(
              [this.callbackNode.current],
              (args) => {
                // do someething
              }
            )
            }
          </Animated.Code>
        )}
        <BottomSheet
          ref={this.bottomSheetRef}
          callbackNode={this.callbackNode}
          snapPoints={[0, '80%']}
          renderHeader={
            () => (
              // your header
            )
          }
          renderContent={
            () => (
              // your content
            )
          }
        />
      </React.Fragment>
    )
}

In this example if args[0] === 1 - sheet is fully opened
if args[0] === 0 sheet is fully closed

tried your solution @ajanauskas but didn't work with me. callbackNode.current is always null.

@songxiaoliang if it works with you, could you please share with us. I'm using functional components and react hooks.

@ajanauskas not working
<ModalBox position="bottom" backButtonClose backdropPressToClose onOpened={this.onModalOpened} onClosed={this.onModalClosed} ref={(ref) => { this.modal = ref; }} > {this.callbackNode.current && ( <Animated.Code> { () => Animated.call( [this.callbackNode.current], (args) => { // do someething alert(args) } ) } </Animated.Code> )} <BottomSheet ref={this.bottomSheetRef} callbackNode={this.callbackNode} snapPoints={[300, 600, 0]} renderContent={() => children} /> </ModalBox>

@paranoia5 not working

@paranoia5 Hooks version:

const MyBottomSheet = (props: Props) => {
  const { onClose } = props
  const bottomSheetRef = useRef<BottomSheet | null>(null)
  const callbackNode = useRef(new Animated.Value(1))

  Animated.useCode(
    Animated.onChange(
      callbackNode.current,
      Animated.block([
        Animated.cond(
          Animated.greaterOrEq(callbackNode.current, 1),
          Animated.call([], () => {
            onClose && onClose()
          })
        ),
      ])
    ),
    [onClose]
  )

  return (
    <React.Fragment>
      <BottomSheet
        ref={bottomSheetRef}
        callbackNode={callbackNode.current}
        initialSnap={0}
        snapPoints={[0, MODAL_HEIGHT]}
        renderHeader={...}
        renderContent={...}
      />
    </React.Fragment>
  )
}

@ajanauskas Can you give an example of not using hooks?

Any use without hooks? Or a possible library fix? Why is it always null anyway?

@songxiaoliang @jcatink Here you have code which works with normal classes :) I hope it will help:
Snack: https://snack.expo.io/HJgqFIq-S
Code:

import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import Animated from 'react-native-reanimated'
import Constants from 'expo-constants';
import BottomSheet from 'reanimated-bottom-sheet';

// You can import from local files
import AssetExample from './components/AssetExample';

// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';

class MySheet extends React.Component {
  bottomSheetRef = React.createRef();
  callbackNode = new Animated.Value(0);
  throttleFlag = false;

  state = {
    callback: 0,
  }

  setCallback = (callback) => {
    if (!this.throttleFlag) {
      this.throttleFlag = true
      setTimeout(() => {
        this.throttleFlag = false
        this.setState({ callback })
      }, 100)
    }
  }

  render() {
    return (
      <React.Fragment>
        <Text style={styles.paragraph}>Callback: {this.state.callback}</Text>
        <Animated.Code exec={() => Animated.block([Animated.call([this.callbackNode], ([callback]) => this.setCallback(callback))])} />
        <BottomSheet
          ref={this.bottomSheetRef}
          callbackNode={this.callbackNode}
          snapPoints={[100, "80%"]}
          renderHeader={() => <View style={styles.header}><Text>GRAB ME</Text></View>}
          renderContent={() => (
            <Card>
              <AssetExample />
            </Card>
          )}
        />
      </React.Fragment>
    );
  }
}

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <MySheet />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  header: {
    alignSelf:'center',
    backgroundColor: 'turquoise',
    width: 200,
    height: 20,
  },
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  paragraph: {
    top: 100,
    left: 50,
    position:"absolute",
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
  },
});

I want to implement a close callback that listens to the bottom-sheet. How do I implement this?

Isn't it enough to set an additional lowest snapPoint (in case you already don't have one with 0 value) and check whether callbackNode equals to 0? Or is more like in #81 and the issue can also be closed?

Closing due to lack of activity, feel free to create a new issue report if presented solutions were not suffictient.

Was this page helpful?
0 / 5 - 0 ratings