使用数组数组生成本机列表视图

时间:2017-11-23 19:59:49

标签: javascript android reactjs react-native

我正在尝试将状态中的输入数据呈现到ListView中。我得到一个TypeError:undefined不是一个对象。

import React, { Component } from 'react';
import { View, Text, Picker, StyleSheet, ListView } from 'react-native'

class BeerPicker extends Component {
  constructor(props){
      super(props);
      this.state = {
          beer = []
          dataSource: new ListView.DataSource({
              rowHasChanged: (row1, row2) => row1 !== row2,
          }).cloneWithRows(['string1', 'string2', 'string3']),
      };
      this.addBeer = this.addBeer.bind(this);
  }
  addBeer(itemValue, itemIndex){ 
    this.setState({
        beer: [...this.state.beer, itemValue]
    });
  }

  renderRow(data) {
    return (
      <Text>{`\u2022 ${data}`}</Text>
    );
  }

   render() {
      return (
         <View>
            <Picker selectedValue = {this.state.dataSource} onValueChange = {this.addBeer}>
               <Picker.item label = 'Choose Beer' value = 'none' />
               <Picker.Item label = "IPA" value = "ipa" />
               <Picker.Item label = "Pilsner" value = "pilsner" />
               <Picker.Item label = "Stout" value = "stout" />
            </Picker>
            <ListView
            dataSource={this.state.beer}
            renderRow={this.renderRow}
            />

         </View>
      )
   }
}
export default BeerPicker;

const styles = StyleSheet.create({
   text: {
      fontSize: 30,
      alignSelf: 'center',
      color: 'black'
   }
})

之前我的状态只是一个空数组,其中addBeer函数绑定到构造函数。现在我想将数据渲染到listview中,但现在它不起作用。我是否必须将数据源绑定到构造函数?

1 个答案:

答案 0 :(得分:1)

您的代码缺少一些内容。

首先,在rowHasChanged回调之后还有一个额外的昏迷。

其次,Picker期望selectValue只有一个值,你传递一个数据源。

最后,ListView需要一个dataSource,但是你要传递一个数组。

试试这个代码段:

constructor(props){
  super(props);

  //This could be a constant out of your component
  this.ds = new ListView.DataSource({rowHasChanged: (row1, row2) => row1 !== row2});

  this.state = {
    beer: [],
    beerDataSource: this.ds.cloneWithRows([]),
    dataSource: this.ds.cloneWithRows(['string1', 'string2', 'string3']) //It seems to be not needed...
  };

  this.addBeer = this.addBeer.bind(this);
}

addBeer(itemValue, itemIndex){ 
  let newBeerArray = [...this.state.beer, itemValue];
  this.setState({
    beer: newBeerArray,
    beerDataSource: this.ds.cloneWithRows(newBeerArray);
  });
}

render() {
  return (
    <View>
      <Picker selectedValue = {this.state.dataSource/* revise this, this should be a unique value */} onValueChange = {this.addBeer}>
        <Picker.item label = 'Choose Beer' value = 'none' />
        <Picker.Item label = "IPA" value = "ipa" />
        <Picker.Item label = "Pilsner" value = "pilsner" />
        <Picker.Item label = "Stout" value = "stout" />
      </Picker>
      <ListView
        dataSource={this.state.beerDataSource}
        renderRow={this.renderRow}/>
    </View>
  )
}

在这里,您将找到组件的改进版本。我没有经过测试,但它应该可以正常工作。让我知道你需要什么。

import React, { Component } from 'react';
import { View, Text, Picker, StyleSheet, ListView } from 'react-native'

const ds = new ListView.DataSource({rowHasChanged: (row1, row2) => row1 !== row2});

export default class BeerPicker extends Component {
    constructor(props){
      super(props);

      this.state = {
        beer: [],
        beerDataSource: ds.cloneWithRows([]),
        dataSource: ds.cloneWithRows(['string1', 'string2', 'string3']), //It seems to be not needed...
        items: [
          {label: 'Choose Beer', value: 'none'}, 
          {label: 'IPA', value: 'ipa'}, 
          {label: 'Pilsner', value: 'pilsner'}, 
          {label: 'Stout', value: 'stout'}
        ],
        selectedItem: 'none'
      };

      this.addBeer = this.addBeer.bind(this);
    }

    addBeer(itemValue, itemIndex){ 
      let newBeerArray = [...this.state.beer, itemValue];
      this.setState({
        beer: newBeerArray,
        selectedItem: itemValue,
        beerDataSource: ds.cloneWithRows(newBeerArray);
      });
    }

    renderRow(data) {
      return (
        <Text>{`\u2022 ${data}`}</Text>
      );
    }

    render() {
      let items = this.state.items.map((item, index) => {
        return (<Picker.item label={item.label} value={item.value} key={index}/>);
      });

      return (
        <View>
          <Picker selectedValue={this.state.selectedItem} onValueChange = {this.addBeer}>
            {items}
          </Picker>
          <ListView
            dataSource={this.state.beerDataSource}
            renderRow={this.renderRow}/>
        </View>
      )
    }
}

const styles = StyleSheet.create({
   text: {
      fontSize: 30,
      alignSelf: 'center',
      color: 'black'
   }
});