React Native ArrayIndexOutOfBoundsException

[亡魂溺海] 提交于 2020-02-25 04:15:28

问题


I am using Picker component from React Native.

I have two Picker components:

  1. State (stateList() function)

  2. City (cityList() function)

I am calling two APIs:

  1. apiState() function: it loads the list of State

  2. apiCity(state_identification) function: based on the State selected, this function will display a list of City

(code snippet provided below)

Code Snippet:

    constructor(props) {
        super(props);
        this.state = {
            pickerValueState: null,
            dataState: [],

            pickerValueCity: null,
            dataCity: [],

            isLoading: true,
        }
    }

    componentDidMount() {
        console.log('ComponentDidMount()')
        this.apiState();
    }

    apiState() {
        let self = this;
        AsyncStorage.getItem('my_token').then((keyValue) => {
            axios({
                method: 'get',
                url: Constants.API_URL + 'user_c/cState/',
                responseType: 'json',
                headers: {
                    'X-API-KEY': Constants.API_KEY,
                    'Authorization': keyValue,
                },
            })
                .then(function (response) {
                    console.log('apiState() Success Response response.data.state: ', response.data.state);
                    self.setState({
                        dataState: response.data.state,
                    });
                })
                .catch(function (error) {
                    console.log('Error (1st): ', error);
                });
        }, (error) => {
            console.log('Error (2nd): ', error) //Display error
        });
    }

    stateList() {
        return (
            <View>
                <Text h4 h4Style={{ textAlign: 'center' }}>Select Location</Text>
                <Text h4 h4Style={styles.location}>State</Text>
                <View style={styles.pickerContainer}>
                    <Picker
                        mode="dropdown"
                        selectedValue={this.state.pickerValueState}
                        onValueChange={(itemValue, itemIndex) => {
                            this.setState({ pickerValueState: itemValue });
                            this.apiCity(itemValue);
                            console.log('State selected (itemValue): ', itemValue);
                        }}
                    >
                        {
                            this.state.dataState.map((item, key) => (
                                <Picker.Item label={item.state_desc} value={item.state} key={key} />)
                            )
                        }
                    </Picker>
                </View>
            </View>
        );
    }

    apiCity(state_identification) {
        let self = this;
        AsyncStorage.getItem('my_token').then((keyValue) => {
            axios({
                method: 'post',
                url: Constants.API_URL + 'user_c/cCity/',
                data: {
                    state_id: state_identification,
                },
                responseType: 'json',
                headers: {
                    'X-API-KEY': Constants.API_KEY,
                    'Authorization': keyValue,
                },
            })
                .then(function (response) {
                    console.log('apiCity() Success Response response.data.city: ', response.data.all_city);
                    self.setState({
                        pickerValueState: state_identification,
                        dataCity: response.data.all_city,
                    });
                })
                .catch(function (error) {
                    console.log('Error (1st): ', error);
                });
        }, (error) => {
            console.log('Error (2nd): ', error) //Display error
        });
    }

    cityList() {
        return (
            <View>
                <Text h4 h4Style={styles.location}>City</Text>
                <View style={styles.pickerContainer}>
                    <Picker
                        mode="dropdown"
                        selectedValue={this.state.pickerValueCity}
                        onValueChange={(itemValue, itemIndex) => {
                            this.setState({ pickerValueCity: itemValue });
                            console.log('City selected (outside itemValue): ', itemValue);
                        }}
                    >
                        {
                            this.state.dataCity.map((item, key) => (
                                <Picker.Item label={item.city_desc} value={item.city} key={key} />)
                            )
                        }
                    </Picker>
                </View>
            </View>
        );
    }

    render() {
        return (
            <View style={styles.container}>
                <Text h3 h3Style={styles.screenTitle}>BookingApp</Text>
                <View style={styles.locationContainer}>
                    {this.stateList()}
                    {this.cityList()}
                </View>
            </View>
        );
    }
}

Before I continue here's what the JSON data and the relation between State and City looks like:

//Lists of states:

{
    "state": [
        {
            "state": "14",
            "state_desc": "Kuala Lumpur"
        },
        {
            "state": "10",
            "state_desc": "Selangor"
        }
    ]
}

//if "state":"14" is selected, these cities are rendered in the picker
{
    "all_city": [
        {
            "city": "262",
            "city_desc": "Kuala Lumpur"
        },
        {
            "city": "263",
            "city_desc": "Sungai Besi"
        }
    ]
}

//if "state":"10" is selected, these cities are rendered in the picker
{
    "all_city": [
        {
            "city": "256",
            "city_desc": "Puchong"
        }
    ]
}

I am facing several issues with my code and these are:

1. ArrayIndexOutOfBoundsExeception: length=1;index=1 (screenshot provided below):

By following this sequence the app crashes 100% of the time:

  • select "state":"14" and "city":"263" (something like this)
  • then select "state":"10"

as soon as "state":"10" is selected, the app will immediately crash and the following bug report is shown:

2. Problem with loading values:

  1. When the app initially loads, these are auto-selected: "state": "14" (State) and "city": "262" (City). Both the APIs gets called and the picker values for State and City gets updated. Similarly, when I select "city": "263" (sungai besi), its picker value gets updated too.

  2. However, when changes are made and the State is changed such as: "state": "10" and "city": "256" (the city picker label auto-changes as it should)... BUT the *Citypicker value* ***doesn't*** get [updated][9] and only theapiCity() function` is called.

  3. Furthermore, when I change state again to: "state": "14" and "city": "262"(the city picker label auto-changes as it should)... BUT, ONCE AGAIN the City picker value doesn't get updated and only the apiCity() function is called.

Lastly, I have tried the following solution(i.e key={item.length}) but it didn't work.

来源:https://stackoverflow.com/questions/60360160/react-native-arrayindexoutofboundsexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!