【问题标题】:React Native Picker ArrayIndexOutOfBoundsExeceptionReact Native Picker ArrayIndexOutOfBoundsException
【发布时间】:2020-02-20 14:51:56
【问题描述】:

我正在使用来自 React Native 的 Picker 组件。

我有两个 Picker 组件:State (stateList() function) 和 City (cityList() function)。我正在调用两个 API:apiState() 函数加载State 的列表,并根据所选的状态,apiCity(state_identification) 函数将显示City 的列表。 (下面提供的代码 sn-p)

代码片段:

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

        pickerValueCity: null,
        dataCity: [],

        isLoading: true,
    }
}

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('Response State Data: ', response.data.state);
                self.setState({
                    dataState: response.data.state,
                    isLoading: false,
                });
            })
            .catch(function (error) {
                console.log('Error (1st): ', error);
            });
    }, (error) => {
        console.log('Error (2nd): ', error) //Display error
    });
}

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,
            },
            /*params: {
                state_id: state_identification,
            },*/
            responseType: 'json',
            headers: {
                'X-API-KEY': Constants.API_KEY,
                'Authorization': keyValue,
            },
        })
            .then(function (response) {
                console.log('Response City Data: ', response.data.all_city);
                self.setState({
                    pickerValueState: state_identification,
                    dataCity: response.data.all_city,
                    isLoading: false,
                });
            })
            .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 })}
                    onValueChange={(itemValue, itemIndex) => {
                        /*this.setState({ pickerValueState: itemValue },
                            () => {
                                this.apiCity(this.state.pickerValueState, itemValue);
                                console.log('State selected: ', (this.state.pickerValueState))
                            }
                        )*/
                        this.apiCity(itemValue)
                    }}
                >
                    {
                        this.state.dataState.map((item, key) => (
                            <Picker.Item label={item.state_desc} value={item.state} key={key} />)
                        )
                    }
                </Picker>
            </View>
        </View>
    );
}

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: ', (this.state.pickerValueCity))
                            }
                        )
                    }}
                >
                    {
                        this.state.dataCity.map((item, key) => (
                            <Picker.Item label={item.city_desc} value={item.city} key={key} />)
                        )
                    }
                </Picker>
            </View>
        </View>
    );
}

render() {
    if (this.state.isLoading) {
        return (
            <View style={{ flex: 1, justifyContent: 'center' }}>
                <ActivityIndicator size="large" color="#0000ff" />
            </View>
        );
    } else {
        return (
            <View style={styles.container}>
                <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. ArrayIndexOutOfBoundsException: length=1;index=1(截图如下):

按照这个顺序,应用程序崩溃 100% 的时间:

  • 选择"state":"10"
  • 然后改为选择"state":"14"和"city":"263"
  • 然后最后再次选择"state":"10"

应用立即崩溃。

2。加载值问题:

当应用最初加载时,"state": "14" 被自动选中,但City 选择器保持为空/不显示标签。

然后,如果我选择 "state":"10",City 选择器会加载值 "city": "256"(并在 console.log 上显示该值)并显示标签 "city_desc": "Puchong"。

但是,当我再次选择 "state": "14" 时,City 选择器不会加载值(不会在 console.log 上显示值),而只会显示标签 "city_desc": "Kuala Lumpur"。只有在我开始在 "city_desc": "Kuala Lumpur" 和 "city_desc": "Sungai Besi" 之间交换时,它才会开始加载值

最后,当我再次选择 "state":"10" 时,City 选择器不会加载值(不会在 console.log 上显示值),而只会显示标签 "city_desc": "Puchong"。

最后,我从这里尝试了以下solution(即key={item.length}),但没有成功。

【问题讨论】:

    标签: javascript react-native axios picker


    【解决方案1】:

    用这个:

     this.setState({ pickerValueState: itemValue },
                            () => {
                                this.apiCity(this.state.pickerValueState);
                                console.log('State selected: ', (this.state.pickerValueState))
                            }
                        )
    

    你有一个州有新州,但旧城的时期。这会导致您的异常。尝试在city api 的响应中设置新state 的状态。所以你同时设置了新的州和新的城市。这可能意味着您应该将新状态作为参数传递给 apiCity 函数,然后在 api 响应中使用它。

    所以在更改事件中只需执行以下操作:

    this.apiCity(this.state.pickerValueState, itemValue);
    

    在apiCityFunction 中,在 setState 中同时获取两者 - 城市和州:

     self.setState({
           pickerValueState: state,
           dataCity: response.data.all_city,
           isLoading: false,
     });
    

    【讨论】:

    • 感谢您的建议。我有点明白你的意思。但是你能举个例子吗?这真的很有帮助。干杯。
    • 在选择器更改事件中:this.apiCity(this.state.pickerValueState, itemValue); 然后在apiCity 中,您将收到选定状态作为参数,并在获取响应后将其传递。设置状态时:self.setState({pickerValueState: state, dataCity: response.data.all_city, isLoading: false, });
    • 我刚刚尝试了您的解决方法,但问题仍然存在。我仍然遇到我提到的两个问题。
    • 在代码 sn-p 中进行了编辑。请检查这是否是您的意思。
    • 差不多。你最好将state 传递给cityApi,但它应该在调用city Api 之前设置state。而不是this.setState({ pickerValueState: itemValue }, () =&gt; { this.apiCity(this.state.pickerValueState); } ) 只是this.apiCity(this.state.pickerValueState);
    猜你喜欢
    • 2021-10-20
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 2020-03-02
    • 2020-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多