React Native - 通过Picker更新ListView

3
我尝试根据Picker选择的'Type'从MySQL中获取数据,并使用获取的数据更新ListView。 因此,当Picker的onValueChange调用componentDidMount()函数以获取新数据并更新ListView时,我会指定一切。
问题是,当我在Picker中选择TypeA时,ListView中的数据不会更新,但是第二次选择Picker中的TypeB时,ListView将基于TypeA进行更新。 然后,我选择TypeC,ListView将基于TypeB进行更新。
我的代码有问题还是我使用了错误的方法?
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>
)
}
}
2个回答

1

您正在手动调用 componentDidMount(),我认为这是错误的做法。

componentDidMount() 在组件被挂载后立即调用。需要使用DOM节点进行初始化的内容应该放在这里。如果您需要从远程端点加载数据,则在此处实例化网络请求是一个好方法。

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

请参阅 组件生命周期以获取更多信息。

现在您的代码看起来很好,在接收到更新的数据后,您可以按如下方式更新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>
  }}
  ...
/>

我尝试创建另一个具有相同代码的函数来调用类似componentDidMount()的功能,但出现了相同的问题,我想知道这是否是fetch()函数的问题。 - I am a Student
你能同时发布带有你的ListView的正确代码吗?很乐意帮助。 - Dev
渲染方法在哪里?请更新问题以提供更好的理解代码。 - Dev
上述代码看起来很好。你在哪里渲染你的ListView,以及你如何尝试更新数据源,请发布一下。 - Dev

0

看起来处理这个问题的更好方法是玩弄componentDidUpdate()而不是componentDidMount()

可以尝试参考下面我完成的应用程序。

Github:https://github.com/slnn3r/RecipeRedux.git

上述项目:

  • 使用Redux架构
  • 使用PHP mySQL数据库
  • 使用堆栈导航

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接