反应本机列表视图添加项目不起作用

jom*_*int 5 listview ios uicollectionview react-native

我是本机反应的新手,我在脑海中实现了一个简单的想法。基本上,我正在做一个“待办事项列表”之类的组件,下面有一个添加按钮,可以添加项目。单击添加按钮后出现问题,列表更新并出现以下 xcode 警告消息。而且我意识到,在实现 ListView 之后,模拟器中的应用程序变慢了,我什至无法检查。在输入一些文本后,警报弹出窗口也会冻结 UI,并且整个应用程序需要重新构建,因为我无法做任何事情。感谢所有的帮助!

主要组件:SurveyQn

'使用严格'

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

var LongButton = require('./LongButton.js');

类 SurveyQn 扩展组件 {

constructor(props) {
    super(props);

    this.state = {
        options: [{option: 'Pizza'}],
    };
}

componentWillMount() {
    this.dataSource = new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2
    })
}

_renderItem(item) {
    return (
        <LongButton 
            text={item.option} 
            onPress={() => {}} 
            //btnViewStyle={styles.buttonView}
            //btnTextStyle={styles.buttonText}
        />
    );
}

_addItem() {
    AlertIOS.alert(
        'Add new option',
        null,
        [
            {
                text: 'Add',
                onPress: (text) => {
                    var options = this.state.options;
                    options.push({option: text})
                    this.setState({ options: options})
                }
            },
        ],
        'plain-text'
    );
}

render(){
    var dataSource = this.dataSource.cloneWithRows(this.state.options);
    return (
        <View style={styles.container}>
            <TextInput
                style={styles.question}
                placeholder="Question title"
                placeholderTextColor="#4B667B"
                selectionColor="#4B667B"
                onChangeText={(text) => this.setState({text})}/>

            <View style={styles.listView}>
                <ListView
                    dataSource={dataSource}
                    renderRow={this._renderItem.bind(this)}/>

            </View>
                <TouchableHighlight 
                    onPress={this._addItem.bind(this)}
                    style={styles.buttonView}
                    underlayColor='rgba(0,0,0,0)'>
                    <Text style={styles.buttonText}>
                        Add option
                    </Text>
                </TouchableHighlight>
        </View>


    );
}
Run Code Online (Sandbox Code Playgroud)

}

var style = StyleSheet.create({ container: { width: 300, flex :1, }, listView: { flex: 1, }, question: { height: 30, fontSize: 20, fontWeight: "100", color: ' #4B667B', marginTop: 10, marginBottom: 10, }, buttonView: { width: 300, paddingVertical: 9, borderWidth: 1, borderColor: '#F868AF', marginBottom: 13, }, buttonText: { textAlign: 'center' , fontSize: 25, color: '#F868AF', fontWeight: '500' }, });

ListView 项目:LongButton

'使用严格'

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

类 LongButton 扩展组件 {

render(){
    return (
        <TouchableHighlight 
            onPress={this.props.onPress}
            style={this.props.btnViewStyle}
            underlayColor='rgba(0,0,0,0)'>
            <Text style={this.props.btnTextStyle}>
                {this.props.text}
            </Text>
        </TouchableHighlight>
    );
Run Code Online (Sandbox Code Playgroud)

} }

module.exports = LongButton;

添加警报项时的 Xcode 警告消息

app[27881:11151280] 未定义 UICollectionViewFlowLayout 的行为,因为: app[27881:11151280] 项目高度必须小于 UICollectionView 的高度减去部分插入顶部和底部值,减去内容插入顶部和底部值。app[27881:11151280] 相关的 UICollectionViewFlowLayout 实例是 <_UIAlertControllerCollectionViewFlowLayout: 0x7ff0685b1770>,它附加到 ; 层 = ; 内容偏移量:{0, 0};contentSize:{0, 0}> 集合视图布局:<_UIAlertControllerCollectionViewFlowLayout:0x7ff0685b1770>。2016-04-06 07:50:01.545 decisionapp[27881:11151280] 在 UICollectionViewFlowLayoutBreakForInvalidSizes 处创建一个符号断点以在调试器中捕获它。

更新: 我试过这个,但它也不起作用。会不会是警报导致了这些问题?单击 btn 后,它只是需要很长时间才能呈现警报。

类 SurveyQn 扩展组件 {

构造函数(道具){ 超级(道具);

   this.state = {
       options: [{option: 'Pizza'}],
       dataSource : new ListView.DataSource({
           rowHasChanged: (row1, row2) => row1 !== row2
       })
   };
Run Code Online (Sandbox Code Playgroud)

}

componentWillMount() { var data = this.state.options; this.state.dataSource.cloneWithRows(data); }

_renderItem(item) { return ( {item.option} ); }

_addItem() { AlertIOS.alert( '添加新选项', null, [ { text: 'Add', onPress: (text) => { var options = this.state.options; options.push({option: text} ) this.setState({ options: options}) } }, ], '纯文本' ); }

渲染(){ 返回(

           <View style={styles.listView}>
               <ListView
                   dataSource={this.state.dataSource}
                   renderRow={this._renderItem.bind(this)}/>

           </View>
               <TouchableHighlight 
                   onPress={this._addItem.bind(this)}
                   style={styles.buttonView}
                   underlayColor='rgba(0,0,0,0)'>
                   <Text style={styles.buttonText}>
                       Add option
                   </Text>
               </TouchableHighlight>
       </View>


   );
Run Code Online (Sandbox Code Playgroud)

} }

Mih*_*hir 1

在深入研究复杂的 EcmaScript 表示法之前,您可以使用简单的表示法。这是 ListView 的一个简单示例。请仔细阅读并了解它是如何工作的。

var API = require('./API');
module.exports = React.createClass({
  getInitialState: function(){
    return {
      rawData: [],
      dataSource: new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2
      }),
      loaded: false,
    }
  },
  componentWillMount: function(){
    this.loadData();
  },
  loadData: function(){
    API.getItems()
    .then((data) => {
      this.setState({
        rawData: this.state.rawData.concat(data),
        dataSource: this.state.dataSource.cloneWithRows(data),
        loaded: true,
      });
    });
  },
  render: function(){
    return(
        <ListView 
          dataSource={this.state.dataSource}
          renderRow={this.renderItem}
          style={styles.listView}>
        </ListView> 
    );
  },
  renderItem: function(item){
    return (
      <View>
          <Text>Custom Item</Text>
      </View>
    );
  },
}
Run Code Online (Sandbox Code Playgroud)

在 API.js 中,我从 API 获取数据。

getItems: function(){
        var REQUEST_URL = 'http://api.example.org/item/get?api_key=xxxx;
        return fetch(REQUEST_URL)
            .then((response) => response.json())
            .then((responseData) => {
                return responseData.results.sort(sortByDate);
            });
    }
Run Code Online (Sandbox Code Playgroud)

该代码可能无法工作,因为我还没有测试过。但你可以参考我在 github 上的示例项目。回购协议