naoufal / react-native-accordion

An Accordion Component for React Native
https://www.npmjs.com/package/react-native-accordion
437 stars 101 forks source link

not an issue, a question #31

Open atasmohammadi opened 8 years ago

atasmohammadi commented 8 years ago

Hello,

My Code is down bellow. its working but i got two warnings :

Warning: Failed propType: Invalid prop content supplied to Accordion, expected a single ReactElement. Check the render method of StaticRenderer.

Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of Accordion. It was passed a child from StaticRenderer. See https://fb.me/react-warning-keys for more information.

Any idea how to fix it? or any better way to have multiple contents for each header?

class Courses extends Component {

  constructor(props) {
        super(props);
        this.state = {
          dataSource: new ListView.DataSource({
            rowHasChanged: (row1, row2) => row1 !== row2,
          }),
          loaded: false,
        };
        this.rowPressed = this.rowPressed.bind(this);
    }
  rowPressed(data) {
    console.log('row press');
  }

  fetchData() {
/// fetching data .....
  }

  componentDidMount() {
    this.fetchData();
  }

  render() {
    if (!this.state.loaded) {
      return this.renderLoadingView();
    }

    return (
      <View style={{ flex: 1 }}>
      <ListView
        dataSource={this.state.dataSource}
        renderRow={this.renderRow}
        style={styles.listView}
      />
      </View>
    );
  }

  renderRow(data) {
    var header = (
      <View>
          <View style={styles.rowContainer}>
            <View  style={styles.textContainer}>
              <Text style={styles.title}>{data.nid}</Text>
              <Text style={styles.description} numberOfLines={0}>{data.title}</Text>
            </View>
          </View>
          <View style={styles.separator}/>
        </View>
    );
///////////
    var content = [];
    for(var x=0; x < Object.keys(data.course).length; x++){
      content.push(
        <View style={styles.rowContainer}>
        <TouchableHighlight onPress={() => this.rowPressed(data.course[x].course_id).bind(this)} underlayColor='#e3e0d7'>
        <Text style={styles.child}>{data.course[x].title}</Text>
        </TouchableHighlight>
        </View>
      );
    }
////////////
    return (
      <Accordion
        header={header}
        content={content}
        easing="easeOutCubic"
      />
    );
  }

  renderLoadingView() {
    return (
      <View style={styles.loading}>
        <Text style={styles.loading}>
          Fetching Courses, please wait...
        </Text>
      </View>
    );
  }
}

module.exports = Courses;

Thanks in Advance!

abritez commented 7 years ago

Whenever you create a list of objects you need to add a unique key. There is a second parameter that contains it

renderRow(data, key) { 
    var header = (
      <View key={key}>
          <View style={styles.rowContainer}>
            <View  style={styles.textContainer}>
              <Text style={styles.title}>{data.nid}</Text>
              <Text style={styles.description} numberOfLines={0}>{data.title}</Text>
            </View>
          </View>
          <View style={styles.separator}/>
        </View>
    );

you would also need to do that for the content

var content = [];
    for(var x=0; x < Object.keys(data.course).length; x++){
      content.push(
        <View key={x} style={styles.rowContainer}>
        <TouchableHighlight onPress={() => this.rowPressed(data.course[x].course_id).bind(this)} underlayColor='#e3e0d7'>
        <Text style={styles.child}>{data.course[x].title}</Text>
        </TouchableHighlight>
        </View>
      );
    }