gpt4 book ai didi

android - React Native - 通过 Picker 更新 ListView

转载 作者:太空狗 更新时间:2023-10-29 13:50:06 28 4
gpt4 key购买 nike

我尝试根据在 Picker 上选择的“类型”从 mySQL 中获取数据,并使用获取的数据更新 ListView。因此,当 Picker 的 onValueChange 将调用 componentDidMount() 函数以获取新数据并更新 ListView 时,我指定了所有内容。

问题是,当我在Picker中选择TypeA时,ListView中的数据没有更新,但是当我在Picker中第二次选择TypeB时,ListView是基于TypeA更新的。然后,我选择TypeC,基于TypeB更新的ListView。

是我的代码有问题还是我使用了错误的方法?

export default class ProfileScreen extends Component {

constructor(props) {
super(props);
this.state = {
TypeInput : 'Vegetarian',
isLoading: true,
};

}

static navigationOptions = {
title: 'View/Edit',
};


OpenSecondActivity(id) {
this.props.navigation.navigate('Second', { ListViewClickItemHolder: id });
}

componentDidMount() {

return fetch('https://unsurfaced-cross.000webhostapp.com/getRecipeRN.php',{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({

RecipeType: this.state.TypeInput

})

}).then((response) => response.json())
.then((responseJson) => {

// Fetch Data update the List View Content
let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.setState({
isLoading: false,
dataSource: ds.cloneWithRows(responseJson),

});
})
.catch((error) => {
console.error(error);
});
}

ListViewItemSeparator = () => {
return (
<View
style={{
height: .5,
width: "100%",
backgroundColor: "#000",
}}
/>
);
}

render() {

const { navigate } = this.props.navigation;

if (this.state.isLoading) {
return (
<View style={{flex: 1, paddingTop: 20}}>
<ActivityIndicator />
</View>
);
}


return (
<View style={styles.container}>
<Text style={styles.text}>Recipe Type: </Text>

<Picker
style={{width: 200}}
selectedValue={this.state.TypeInput}
onValueChange={
(itemValue, itemIndex) => {
this.setState({TypeInput: itemValue, isLoading:true})
this.componentDidMount()
this.forceUpdate()
}
}>

<Picker.Item label="Vegetarian" value="Vegetarian" />
<Picker.Item label="Fast Food" value="Fast Food" />
<Picker.Item label="Healthy" value="Healthy" />
<Picker.Item label="No-Cook" value="No-Cook" />
<Picker.Item label="Make Ahead" value="Make Ahead" />

</Picker>

<ListView

dataSource={this.state.dataSource}

renderSeparator= {this.ListViewItemSeparator}

renderRow={(rowData) => <Text style={styles.rowViewContainer}
onPress={this.OpenSecondActivity.bind(this, rowData.RecipeID)}> {rowData.RecipeName} </Text>}

/>



</View>
)
}
}

最佳答案

您手动调用 componentDidMount() 我认为这是错误的做法。根据文档

componentDidMount() is invoked immediately after a component is mounted. Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request.

在您的情况下,我建议您在更改选择器中的值时,使用一些不同的处理函数来负责更新状态。您不应手动调用 componentDidMount(),因为它是组件的生命周期 Hook 之一。

更多关于 Component Lifecycle .

上面的代码现在看起来没问题,在你的代码中,一旦你收到更新的数据,你就可以更新 ListView 的数据源,如下所示,

...
fetch('https://unsurfaced-cross.000webhostapp.com/createRN.php', {
...
.then((responseJson) => {
this.setState({dataSource: responseJson})
}
...

而你的ListView,应该是这样的

<ListView
automaticallyAdjustContentInsets={false}
dataSource={ds.cloneWithRows(this.state.dataSource)}
renderRow={(rowData)=> {
return <View>
<Text style={rowStyle.label} content={rowData.someField} />
</View>
}}
...
/>

关于android - React Native - 通过 Picker 更新 ListView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49188224/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com