如何在 FlatList 上的 renderItem 中调用 fetch()? [英] How to call fetch() inside renderItem on FlatList?

查看:19
本文介绍了如何在 FlatList 上的 renderItem 中调用 fetch()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到目前为止我一直无法解决这个问题,我希望这里的人可以帮助我:)

I have been unable to solve this so far, I hope someone from here can help me :)

情况如下:

  1. 我使用一个以 JSON 格式返回的 API 加载了一个部门的用户列表(这可行).

  1. I load a list of users from a department using an API which returns it as JSON (this works).

对于 JSON 文件中的每个用户,我必须获取另一个包含传感器数据的 JSON 文件(这不起作用).

For each user in the JSON file, I have to fetch another JSON file containing sensor data (this does not work).

我实际上能够从 getStatus() 函数中获取 JSON 数据,但这是不正确的.因为,当 FlatList 被渲染时,数据仍然没有被获取,但是在刷新时,调用 fetchUsers(),传感器数据显示出来,但它在所有用户上显示相同的传感器数据而不是他们自己的特定传感器数据.

I am in fact capable of getting the JSON data from the getStatus() function, but it is not correct. Because, when the FlatList is rendered, the data still has not been fetched, but on refresh, calling fetchUsers(), the sensor data shows up, but it shows the same sensor data on all users and not their own specific sensor data.

目前我已经让它吐出它在 Text 元素中接收到的任何 JSON,以便查看返回的内容......

At the moment I have made it spit out what ever JSON it receives in a Text element in order to see what was returned...

我不允许在这里上传图片,但我在 Imgur 上制作了一个相册,其中包含应用程序的图像以帮助解释问题:https://imgur.com/a/5XLpR

I am not allowed to upload pictures here, but I have made an album on Imgur which contains images of the application to help explain the issue: https://imgur.com/a/5XLpR

export default class SensorData extends Component {
constructor(props) {
    super(props);
    this.stats = null;
    this.state = { 
        isLoading: true,
        error: false,
        userDataSource: [],
        refreshing: false,
        time: 30,
        navigation: props.navigation,
    };
}

componentDidMount() {
    this.fetchUsers();
}

fetchUsers(){
    return fetch('http://url-to-the-json/json/patients.json')
        .then((response) => response.json())
        .then((response) => {
            this.setState({
                isLoading: false,
                error: false,
                userDataSource: response,
                refreshing: false,
                time: 30,
            }, function () {

            });
        })
        .catch((error) => {
            this.setState({
                isLoading: false,
                error: true
            })
        });
}

getStatus(patientId) {
    fetch("http://url-to-the-json/json/status/" + patientId + ".json")
        .then((response) => response.json())
        .then((responseJson) => {
            this.stats = responseJson;
        })
        .catch((error) => {
            Alert.alert("Error");
        });
    return this.stats;
};

renderItem(item, index) {
    var x = index % 2 === 0;
    status = this.getStatus(item.patientId);
    return (
        <View style={x ? styles.rowEven : styles.rowOdd}>
            <TouchableOpacity style={styles.rowName} onPress={this.handlePress.bind(this, item)}>
                <Text style={styles.rowNameText}>{item.firstname} {item.lastname}</Text>
            </TouchableOpacity>
            <Text>{JSON.stringify(status)}</Text>
        </View>          
    )
}

render() {
    return (
        <View>
            <View style={styles.reloadTimer}>
                <Text style={styles.timerText}>Reloading in {this.state.time} seconds.</Text>
            </View>
            <View style={styles.listView}>
            <FlatList
                    data={this.state.userDataSource}
                    renderItem={({ item, index }) => this.renderItem(item, index)}
                    keyExtractor={item => item.patientId}
                    refreshing={this.state.refreshing}
                    onRefresh={this.handleRefresh}
                    ItemSeparatorComponent={this.renderSeparator}
            />
            </View>
        </View>
    );
}
}

变量status是有问题的.

我希望我以一种可以理解的方式提出了这个问题.

I hope I formulated the question in an understandable manner.

用户 JSON 文件如下所示:

  {
    "patientId": "ec276ca9-f9ab-429b-b34e-23fcf448d714",
    "firstname": "Julie",
    "lastname": "Nielsen",
    "birthDate": "1930-01-01T00:00:00Z",
    "departmentId": "709f59ae-67fe-447c-bed3-7b5912703861",
    "patientNumber": null,
    "entryDate": null,
    "dischargeDate": null,
    "editedOn": null,
    "editedBy": null
  }

传感器数据 JSON 文件如下所示:

{
"status": {
      "in_bed": false,
      "in_room": true,
      "clean_diaper": true
    }
}

推荐答案

您需要将 getStatus 的结果存储在组件状态中,就像使用患者 JSON 一样.假设您的状态中有一个统计"对象将患者映射到他们的统计数据,您可以这样做:

You need to store the result of getStatus in component state like you do with the patients JSON. Assuming you have a "stats" object in your state that maps a patient to their stats, you can do:

getStatus(patientId) {
    fetch("http://url-to-the-json/json/status/" + patientId + ".json")
        .then((response) => response.json())
        .then((responseJson) => {
            let stats = Object.assign({}, this.state.stats);
            stats[patientId] = responseJson;
            this.setState({ stats: stats });
        })
        .catch((error) => {
            Alert.alert("Error");
        });
};

然后,在 renderItem 函数中,您可以从状态渲染统计信息,或者如果尚未加载统计信息,则渲染占位符文本.此外,您不应该在渲染函数中发出网络请求,因为它们可能会被同一个组件频繁地多次调用.相反,您应该查看 FlatList API 和可见性更改的回调.

Then, in the renderItem function, you can render the stats from state, or render a placeholder text if the stats haven't been loaded yet. Also, you should not make network requests inside a render function, since they can be called quite often and multiple times for the same component. Instead, you should look into the FlatList API and the callbacks for changes in visibility.

希望对你有帮助……

这篇关于如何在 FlatList 上的 renderItem 中调用 fetch()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆