React Native ArrayIndexOutOfBoundsException - PullRequest
       86

React Native ArrayIndexOutOfBoundsException

1 голос
/ 23 февраля 2020

Я использую Picker компонент от React Native.

У меня есть два компонента Picker:

  1. State (stateList() function)

  2. City (cityList() function)

Я вызываю два API:

  1. apiState() function: загружается список State

  2. apiCity(state_identification) function: на основе выбранного State эта функция будет отображать список City

( фрагмент кода, представленный ниже )

Фрагмент кода :

    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>
        );
    }
}

Прежде чем продолжить, вот как выглядят данные JSON и соотношение между State и City:

//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"
        }
    ]
}

Я столкнулся с несколькими проблемами с моим кодом, а именно:

1. ArrayIndexOutOfBoundsExeception: length = 1; index = 1 ( снимок экрана представлен ниже ):

При выполнении этой последовательности приложение вылетает 100% времени:

, как только будет выбран "state":"10", приложение немедленно обработает sh и отобразится следующий отчет об ошибке:

enter image description here

2. Проблема с загрузкой значений :

  1. При первоначальной загрузке приложения это с автоматическим выбором : "state": "14" (штат) и "city": "262" (город ). И API-интерфейс вызывается, и значения выбора для State и City получают обновленный . Точно так же, когда я выбираю "city": "263" ( sungai besi ), его значение выбора также обновляется .

  2. Однако, когда изменения сделаны и State изменяется таким образом: "state": "10" и "city": "256" ( метка выбора города автоматически изменяется , как и должно) ... НО * City picker value* ***doesn't*** get [updated][9] and only the apiCity () function` вызывается.

  3. Кроме того, когда я снова меняю состояние на: "state": "14" и "city": "262" ( метка выбора города автоматически изменяет как положено) ... НО, ЕЩЕ РАЗ Значение выбора города не получить обновлено и вызывается только apiCity() function.

Наконец, Я попробовал следующее решение ( т.е. key={item.length}) но это не сработало.

...