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

rowLayout undefined on initial row render

Open danielreuterwall opened this issue 8 years ago • 3 comments

Hi,

I've got an issue when I pass some initial data to SortableList. In _renderRows() it tries to get width from rowsLayouts[key] but rowsLayouts[key] is undefined. If I pass the data with a delay, setting the data prop after SortableList has mounted everything works.

Then I tried to change the if statement in _renderRows() from if (rowsLayouts) to if(rowsLayouts && rowsLayouts[key]) then it works without the delay.

Not sure if I missed something in the logic or if this is a valid fix. What do you think @gitim?

danielreuterwall avatar Nov 17 '17 12:11 danielreuterwall

Hi, could you provide a gist that reproduce the bug, because it looks like you have some specific case?

gitim avatar Nov 17 '17 22:11 gitim

Hi, sorry for the delay. I just created a new clean react native app and added a sortableList with some random images seen below and the error come when you start the app. If a add a timeout in componentDidMount before I set photos in the component state, it works without my fix. However that doesn't seem like a solid fix. The fix I mentioned above does resolve it without the need for a timeout.

I haven't found out why it works with the timeout, maybe you got the answer fot that. What's your take on this? I could provide a pull request if you'd like.

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from "react";
import { Platform, StyleSheet, Text, View, Image } from "react-native";
import SortableList from "react-native-sortable-list";

const instructions = Platform.select({
  ios: "Press Cmd+R to reload,\n" + "Cmd+D or shake for dev menu",
  android:
    "Double tap R on your keyboard to reload,\n" +
    "Shake or press menu button for dev menu"
});

export default class App extends Component<{}> {
  constructor() {
    super();

    this.state = {
      photos: {}
    };
  }

  componentDidMount() {
    let photos = {};
    for (var i = 0; i < 10; i++) {
      photos[i] = {
        uri:
          "https://via.placeholder.com/80/" +
          Math.random()
            .toString(16)
            .slice(2, 8) +
          "/" +
          Math.random()
            .toString(16)
            .slice(2, 8)
      };
    }

    this.setState({
      photos
    });
  }
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>Welcome to React Native!</Text>
        <Text style={styles.instructions}>To get started, edit App.js</Text>
        <Text style={styles.instructions}>{instructions}</Text>
        {this.state.photos && (
          <SortableList
            horizontal={true}
            style={styles.list}
            data={this.state.photos}
            renderRow={this.renderRow}
            showsHorizontalScrollIndicator={false}
            removeClippedSubViews={false}
          />
        )}
        <Image
          source={{ uri: "https://via.placeholder.com/80x80" }}
          style={{ width: 80, height: 80 }}
        />
      </View>
    );
  }

  renderRow({ data, active, key }) {
    return (
      <Image
        key={key}
        source={data}
        style={{
          width: active ? 70 : 80,
          height: active ? 70 : 80,
          marginRight: 10
        }}
      />
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#F5FCFF"
  },
  welcome: {
    fontSize: 20,
    textAlign: "center",
    margin: 10
  },
  instructions: {
    textAlign: "center",
    color: "#333333",
    marginBottom: 5
  }
});

danielreuterwall avatar Nov 22 '17 11:11 danielreuterwall

@gitim Any thoughts on this?

danielreuterwall avatar Jan 23 '18 15:01 danielreuterwall