Home > Enterprise >  Trigger method on parent component from child component - react
Trigger method on parent component from child component - react

Time:01-25

I have a swipeable component with an open and close function that I would like to trigger from a child of the component. I don't think using state to do it in this instance would be correct since I want to avoid a re-render while the swipeable component is animating (please correct me if I'm wrong).

I'm using react-native-gesture-handler/swipeable and following their example here

SwipeCard component

import React, { useRef } from 'react';

import { RectButton } from 'react-native-gesture-handler';
import Swipeable from 'react-native-gesture-handler/Swipeable';
import Animated from 'react-native-reanimated';
const AnimatedView = Animated.createAnimatedComponent(View);

export const SwipeCard = ({ children }) => {
  let swipeableRow = useRef(null);

  let renderRightActions = (_progress, dragX) => {
    let scale = dragX.interpolate({
      inputRange: [-80, 0],
      outputRange: [1, 0],
      extrapolate: 'clamp',
    });
    return (
      <RectButton style={styles.rightAction} onPress={close}>
        {/* Change it to some icons */}
        <AnimatedView style={[styles.actionIcon]} />
      </RectButton>
    );
  };

  let close = () => {
    swipeableRow?.close();
  };

  let open = () => {
    swipeableRow?.openRight();
  };

  return (
    <Swipeable
      ref={swipeableRow}
      renderRightActions={renderRightActions}
      friction={2}
      rightThreshold={40}
    >
      {children}
    </Swipeable>
  );
};

Below is the component where I'm using SwipeCard and the Toggle is the event I want to use to fire the open() method in the SwipeCard component.

<Row>
    {arr.map((item) => {
      return (
        <SwipeCard key={item.id}>
          <CardContainer>
            <CleaningCard
              cleaningData={item}
            />
            <Toggle onPress={() => {}}>
              <Icon name="dots" />
            </Toggle>
          </CardContainer>
        </SwipeCard>
      );
    })}
  </Row>

CodePudding user response:

You can use the render prop pattern and pass close, open as arguments.

Parent component where SwipeCard is used:

<Row>
  {arr.map((item) => {
    return (
      <SwipeCard key={item.id}>
        {({ close, open }) => (
          <CardContainer>
            <CleaningCard cleaningData={item} />
            <Toggle
              onPress={() => {
                // close()/open()
              }}
            >
              <Icon name="dots" />
            </Toggle>
          </CardContainer>
        )}
      </SwipeCard>
    );
  })}
</Row>;

SwipeCard component:

<Swipeable
  ref={swipeableRow}
  renderRightActions={renderRightActions}
  friction={2}
  rightThreshold={40}
>
  {children({close, open})}
</Swipeable>

We're simply making the children a function that takes an object and returns the JSX. The required object is passed as an argument (children({close, open})).

  •  Tags:  
  • Related