react-native-sortable-list icon indicating copy to clipboard operation
react-native-sortable-list copied to clipboard

🔥 How does manual row activation work?

Open wmonecke opened this issue 6 years ago • 13 comments

There are several issues here with the same problem. How can we access the method passed to the children?

wmonecke avatar Jan 23 '20 15:01 wmonecke

Hey @wmonecke not sure if you were able to resolve your issue, but by setting the manuallyActivateRows={true} your row component will gain access to an additional prop of toggleRowActive.

You can then add the prop to a longPressIn (or similar) on the row component, and that will apply the default sorting behavior when that event is triggered.

Hope that helps!

sepowitz avatar Feb 06 '20 16:02 sepowitz

No it does not. I have the version 0.0.24 and when I pass the prop manuallyActivateRows={true} to my list, the renderRow props are:

  • key
  • data
  • disabled
  • active
  • index

There is no toggleRowActive

thmsbernard avatar Apr 04 '20 16:04 thmsbernard

@Thomas-Negrault ~ i was confused at first too, but it does work.

elan avatar May 16 '20 20:05 elan

i also tried adding the manuallyActivateRows={true} prop, and am not seeing any toggleRowActive prop. Is there something I'm missing? @elan, if it does work could you maybe show us some of your code? Or why you were initially confused?

Ibeihl avatar May 29 '20 18:05 Ibeihl

I have this:

      <SortableList
        manuallyActivateRows={true}
        ...

Then in the row itself:

  onLongPress = () => {
    if (this.props.toggleRowActive) {
      this.props.toggleRowActive();
    }
    ...

elan avatar May 29 '20 18:05 elan

@Ibeihl The toggleRowActive prop is passed to the outermost component inside the renderRow function.

Good:

renderRow = (props) => {
    return <CustomRowComponent {...props} />
}

toggleRowActive should be accessible in the props of CustomRowComponent

Bad (toggleRowActive is passed to <View>):

renderRow = (props) => {
    return (
        <View>
            <CustomRowComponent {...props}/>
            <AnotherComponent/>
        </View>
    );
}

bureyburey avatar May 29 '20 18:05 bureyburey

Thanks @elan and @bureyburey for the quick responses, I am currently passing the props to my row component correctly since I have been successfully passing data and active to it. I had everything working fine before upgrading to react-native .62, are either of using a version of react native > .60?

Ibeihl avatar May 29 '20 19:05 Ibeihl

Nope, stuck on 0.59.x

elan avatar May 29 '20 19:05 elan

I recently upgraded to 0.62, tho i use the sortable list in an old feature and hadn't tested it since upgrading.

I will update here on the status once i do.

Do you mind sharing your renderRow function?

bureyburey avatar May 29 '20 19:05 bureyburey

so ive tried a bunch of different ways, but as @Thomas-Negrault said, i can access data, active, disabled, index, and key props. But even with manuallyActivateRows, toggleRowActive shows up undefined. Even if i don't destructure the props and console.log the entire props object getting passed into the render function, there is no toggleRowActive

 const renderSortablePlaceCards = ({ data: block, active, toggleRowActive }) => {
    return (
      <TouchableWithoutFeedback
        style={[styles.placeCard, active && styles.activePlaceCard]}
        onPress={() => (sortableActive ? null : navigation.navigate('EditPlaceNotes', { list, modalType: 'editPlace', block }))}
      >
        <View style={[styles.placeCard, active && styles.activePlaceCard]}>
          <FastImage source={dragIcon} />
          <FastImage style={styles.placeCardCover} source={{ uri: block.cover }} />
          <Text style={styles.placeCardText}>{block.place.name}</Text>
        </View>
      </TouchableWithoutFeedback>
    );
  };

Ibeihl avatar May 29 '20 20:05 Ibeihl

@Ibeihl move the entire return statement to a new component:

const renderSortablePlaceCards = ({ data: block, active }) => {
    return <SortablePlaceCard block={block} active={active} />
  };

And the component:

const SortablePlaceCard = ({ block, active, toggleRowActive }) => {
    return (
      <TouchableWithoutFeedback
        style={[styles.placeCard, active && styles.activePlaceCard]}
        onPress={() => (sortableActive ? null : navigation.navigate('EditPlaceNotes', { list, modalType: 'editPlace', block }))}
      >
        <View style={[styles.placeCard, active && styles.activePlaceCard]}>
          <FastImage source={dragIcon} />
          <FastImage style={styles.placeCardCover} source={{ uri: block.cover }} />
          <Text style={styles.placeCardText}>{block.place.name}</Text>
        </View>
      </TouchableWithoutFeedback>
    );
}

The toggleRowActive will be accessible in it (you can remove it from the props destructuring of your function).

The toggleRowActive prop is passed using React.cloneElement as you can see here

In your code, the <TouchableWithoutFeedback> is the one that gets the prop passed to it, but it is inaccessible. By creating a custom SortablePlaceCard component, we can now access it.

bureyburey avatar May 29 '20 21:05 bureyburey

@bureyburey thank you!! I did understand what you were saying before, but creating a separate component solved it, i can now access toggleRowActive.

Ibeihl avatar May 29 '20 21:05 Ibeihl

Aight, great to hear that :)

bureyburey avatar May 29 '20 21:05 bureyburey