首页 > 解决方案 > 获取下一页数据时出现平面列表错误

问题描述

我正在使用 redux 从平面列表中获取数据,在渲染项函数中,我可以看到数据在获取页面记录后正在渲染,它抛出错误不变违规:试图让帧超出范围索引 0

在 renderitem 的调试语句中,我可以看到数据已填充,并且正在控制台中打印数据。下面是我的代码

import React, { Component } from 'react'
import { FlatList, StyleSheet, View, Text,Image,ActivityIndicator,
  Picker,TouchableOpacity,SectionList,DrawerLayoutAndroid,Alert,
 TouchableHighlight,Button} from 'react-native'          
import NumericInput from 'react-native-numeric-input'
import {connect} from 'react-redux';
import AlldataJson from './../Data/AllProduct.json'

import {
  createDrawerNavigator,
  createStackNavigator,
  createAppContainer,
} from 'react-navigation';


const mapStateToProps = (state) =>{ 
    // console.log('I am in mapstate to props '+ JSON.stringify(state));    
    return { 
      datasource:state.datasource,   
      isLoading:state.isLoading,
      switchValue: state.switchValue,
      page:state.page,    
      rerender:state.rerender,
      isFetching: state.isFetching, 
      search:state.search,
      LastSelectedItem:state.LastSelectedItem,
      ItemSelected:state.ItemSelected,
      setdrawerstate:state.setdrawerstate
    }
  };

const mapDispatchToProps=(dispatch)=>{
  // console.log('i am ni map dispatch to props')
  return {
    quantitychange:(prodindex, changevalue)=>dispatch({type:"CHANGE_QTY",
                                                   index:prodindex,
                                                   value:changevalue}),
    selectvaluechange:(index,itemvalue,itemindex)=>dispatch({type:"CHANGE_WEIGHT",
                                                                    index:index,
                                                                    itemvalue:itemvalue,
                                                                    itemindex:itemindex}),
    ToogleDrawerState:(newState)=>dispatch({type:'TOOGLE_DRAWER',newState:newState}), 
    taggleSwitch:(value,ind)=>dispatch({type:'TOOGLE_SWITCH',value:value,ind:ind}),
    fetchAllData:(AlldataJson)=>dispatch({type:'ALL_DATA',AlldataJson:AlldataJson})
    };
};

class DashBoard extends Component {
  constructor(props) {
    super(props)   
    console.log('i am in constructor')
    console.log('the value getting as props is '+JSON.stringify(props));
    // this.selectvaluechange=this.selectvaluechange.bind(this); 
    // this._opendrawer = this._opendrawer.bind(this);   
  } //constructor


  packageList = (index) =>{
    // console.log('i am in package list'+index)
    return( this.props.datasource[index].pack.map( (x,j) => { 
          return( <Picker.Item label={x.Weight} key={j} value={x.packId}/>)}));
}
// Verdana 20

  renderItem = ({ item,index }) => {
    //  console.log('i am in render item index is '+index+' item vale is '+JSON.stringify(item));
      return(
      <View style={{
        flex: 1, flexDirection: 'row', marginBottom: 3,
        paddingBottom: 10, paddingTop:10, paddingLeft: 10, backgroundColor: 'white', height: '25%'
      }}>
        <View style={{ width: '30%' }}>
          <Image style={{ resizeMode: 'contain', height: '100%',width:'100%' }}
            source={{ uri: this.props.datasource[index].imageUrl }} />
        </View>
        <View style={{ alignContent: 'center', paddingLeft: 40, width: '65%' }}>
          <Text style={{
            fontSize: 20, color: 'black', fontWeight: 'bold',
            fontFamily: 'Verdana'
          }}>
            {item.Heading}</Text>
          <Text style={{
            fontSize: 12, paddingTop: 10, fontFamily: 'Verdana',
            color: 'black', fontWeight: 'bold'
          }}>{item.Details}</Text>
          <View style={{ flex: 1, flexDirection: 'row', paddingTop: 15 }}>
            <Text style={{ width: 40, height: 30, fontFamily: 'Verdana', fontWeight: 'bold' }}>Qty :</Text>
            <NumericInput
              totalHeight={30}
              totalWidth={80}
              minValue={0}
              value={this.props.datasource[index].Qty}
              onChange={(value) => this.props.quantitychange(index, value)} />
            <Picker
              style={{ marginLeft: 10, width: '45%', height: 40, fontFamily: 'Verdana', fontWeight: 'bold' }}
              mode="dropdown"
              selectedValue={this.props.datasource[index].packselectedValue}
              onValueChange={(itemValue, itemIndex) => this.props.selectvaluechange(index, itemValue, itemIndex)}>
              {this.packageList(index)}
            </Picker>
          </View>
          <View >
            <Text style={{ fontFamily: 'Verdana', fontWeight: 'bold' }}>Price  : {this.props.datasource[index].
              pack[this.props.datasource[index].packselectedValue].Price}
              <Text style={{ fontFamily: 'Verdana', fontWeight: 'bold' }}>     Amount : {this.props.datasource[index].
                pack[this.pack.datasource[index].packselectedValue].Price *
                this.props.datasource[index].Qty}
              </Text>
            </Text>
          </View>
        </View>
      </View>
    )  
  }

renderSeperator=()=>{
  console.log('I am renderseperator the data ')
  return(
   <View style={{height:1,width:'100%',backgroundColor:'black'}}/>
  )
}

 onRefresh=()=>{
    console.log('I am refreshing the data '+this.props)
   // this.setState({isFetching:false})
 }

 componentDidMount() {

    console.log('i am in component didmount ');
    const url='./../Data/AllProduct.json'    
    // ./../Data/AllProduct.json'
    fetch(url)
      .then((response) => response.json())
      .then((responsejson => {
        console.log('i am in response json')      
         fetchAllData(responsejson)}))

        //this.setState({ datasource: responsejson })})
      .catch((error) => {        
        console.log('error in fetching the data bhasker')
        this.props.fetchAllData(AlldataJson);
        console.log('i am after fetchalldata function'+this.props)
      })
      this.props.navigation.setParams({ opendrawer: this._opendrawer});      
  }
  // data={this.state.page===1?this.state.datasource:[this.state.datasource]}

  render() {
    //  console.log('I am in render '+JSON.stringify(this.props.datasource)); 
     return (
      this.props.isLoading ? 
      <View style={{ flex: 1, justifyContent: 'center', alignContent: 'center' }}>
        <ActivityIndicator size='large' color='#330066' animating />
      </View> : <View>                   
                     <FlatList data={this.props.datasource}
                                renderItem={(item,index)=>this.renderItem(item,index)}
                                keyExtractor={item=>item.Id}
                                debug='yes'/>
              </View>
     )
  }
}

export default connect(mapStateToProps,mapDispatchToProps)(DashBoard);



/* Reducer is */
import * as types from '../Action/ActionType'
import { objectExpression } from '@babel/types';
import Allproduct from './../Data/AllProduct';

const initialstate={    
        datasource: [],
        isLoading:false,
        switchValue: true,
        page:1,    
        rerender:true ,
        isFetching: false, 
        search:"" ,
        LastSelectedItem:{Item:"",qty:"",weight:""},
        ItemSelected:0,
        setdrawerstate:true
      }

const reducer = (state = initialstate, action) => {
    // console.log('i am in reducer '+JSON.stringify(action));
    switch (action.type) {         
        case "CHANGE_QTY": 
            break;
        case "CHANGE_WEIGHT":
            break;
        case "TOOGLE_DRAWER": 
            break;
        case "TOOGLE_SWITCH": 
            break;
        case "ALL_DATA": 
            console.log('i am in all data') ; 
            return {...state,
                datasource:action.AlldataJson};       
       default:
            return state;
    }

}   

export default reducer;

/* All product json is */
[{"Id":"1","Heading":"Ashirvad","Details": "ashirvad Atta - Whole Wheet 10k Pouch",
    "imageUrl": "https://www.aashirvaad.com/images/packet-2-right.png",                                            "Qty": 0,
"pack": [{"packId":0,"Weight": "1kg","Price": 25},
    {"packId":1,"Weight": "2kg","Price": 50}, 
    {"packId":2,"Weight": "5kg","Price": 125},
    {"packId":3,"Weight": "10kg","Price": 250}],
    "packselectedValue":0,"isselected": false},
{"Id":"2","Heading": "Tata Salt","Details": "Tata Salt Iodised Salt 1kg Product",
"imageUrl": "http://tatasalt.com/public/front_assets/images/tab-product-img1.png",
"Qty": 0,
"pack": [{"packId":0,"Weight": "1kg","Price": 9.5},{"packId":1,"Weight": "2kg","Price": 19}, {"packId":2,"Weight": "5kg","Price": 47    },
{"packId":3,"Weight": "10kg","Price": 92}],"packselectedValue":0,"isselected": false}]

这是我得到的错误

标签: react-native

解决方案


它发生是因为你有debug='yes',FlatList并且它data最初是一个空数组。要消除错误,以下任何一个都应该起作用:

  • 移除debug道具
  • 在初始数据中添加一些虚拟元素
  • View如果data数组没有任何元素,则呈现其他一些组件(如 a )


顺便说一句,这行中的函数参数/参数FlatList

renderItem={(item,index)=>this.renderItem(item,index)}

应该有花括号 ( {})

renderItem={({item,index})=>this.renderItem({item,index})}


或者更好的是,只需将其更改为renderItem={this.renderItem}

如果它解决了问题,请接受这个答案。谢谢 :)


推荐阅读