【问题标题】:How to get the return from Axios.get and Render components dynamically on a Functional Component如何在功能组件上动态获取 Axios.get 和 Render 组件的返回
【发布时间】:2020-09-21 07:33:55
【问题描述】:

我有一个功能组件,我正在尝试从 axios.get() 获取数据并根据请求的响应动态呈现一些组件。

如果我console.log 响应是Ok,但我的问题是如何使用来自axios.get() 的返回在屏幕上创建组件。

我尝试了一个简单的数组,使用它我可以创建组件。我想要的是在屏幕上以与数组相同的方式创建组件。

在发布自己的帖子之前,我已经阅读了很多帖子。非常感谢一些帮助或指导。

import React, { createElement, useState, useEffect } from 'react';
import { Text, StyleSheet, View, TouchableOpacity, Image } from 'react-native';
import axios from 'axios';

const HomeScreen = ({ navigation }) => {

  axios.get("http://100.103.16.113:8081/api/checklists", {
  }).then
    (function (response) {
      console.log(response.data);
    }).catch(error => {
      console.log(error);
    })
  const checklists = [{
    "id": 1,
    "checklisT_DESCRIPTION": "CHECKLIST 1"
  },
  {
    "id": 2,
    "checklisT_DESCRIPTION": "CHECKLIST 2"
  },
  {
    "id": 3,
    "checklisT_DESCRIPTION": "CHECKLIST 3"
  }
  ]
  return (
    <View >
      <Text style={styles.text}> Select an Audit</Text>

      <View style={styles.maincontainer}>
        <View style={styles.container}>

          {}
          {checklists.map(r => (

            <TouchableOpacity onPress={() => navigation.navigate('AuditS')} style={styles.button}
            >
              <Image source={require('../assets/icons8-audit-80.png')} style={styles.Image}></Image>
              <Text style={styles.ButtonText}>{r.checklisT_DESCRIPTION}</Text>

            </TouchableOpacity >
          ))}

        </View>
      </View>
      <View style={styles.bottomcontainer}>
        <TouchableOpacity onPress={() => navigation.navigate('Login')}
        >
          <Text style={styles.logout}>LOGOUT</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
};
const styles = StyleSheet.create({
  text: {
    fontSize: 50,
    fontFamily: 'Comfortaa-Regular',
    alignItems: "center",
    textAlignVertical: "center",
    textAlign: "center",
    justifyContent: "center",
  },
  container: {
    marginTop: 50,
    flexDirection: "row",
    marginLeft: 50,
    width: '100%'
  },
  maincontainer: {
    flexDirection: "column",
    width: '80%',
    alignContent: "center",
    justifyContent: "center",
  },
  bottomcontainer: {
    marginTop: '70%',
    width: '100%',
    alignItems: "center",
    justifyContent: "flex-end",
    alignContent: "flex-end",
  },
  logout: {
    marginTop: 50,
    margin: 15,
    height: 60,
    width: 440,
    borderColor: '#000000',
    backgroundColor: '#000000',
    borderWidth: 2,
    borderRadius: 10,
    fontSize: 18,
    textAlign: "center",
    textAlignVertical: "center",
    color: "#FFFFFF",
    fontFamily: 'Comfortaa-Bold'
  },
  button: {
    backgroundColor: '#0f99f5',
    fontSize: 16,
    color: '#FFF',
    width: 150,
    height: 150,
    borderRadius: 10,
    textAlignVertical: "bottom",
    textAlign: "center",
    marginVertical: 20,
    marginHorizontal: 10,
    fontFamily: 'Comfortaa-Bold'
  },
  ButtonText: {
    textAlignVertical: "bottom",
    textAlign: "center",
    fontSize: 16,
    color: '#FFF',
    marginHorizontal: 10,
    fontFamily: 'Comfortaa-Bold'
  },
  Image: {
    width: "50%",
    height: "50%",
    alignContent: "center",
    alignSelf: "center",
    marginTop: 10,
    marginBottom: 10
  }
});

export default HomeScreen;

【问题讨论】:

    标签: javascript reactjs react-native axios


    【解决方案1】:

    您需要在组件内部使用状态。

    import React, { createElement, useState, useEffect  } from 'react';
    
    
    const HomeScreen = ({ navigation }) => {
    
      const [checkList, setCheckList] = useState([{
                    "id": 1,
                    "checklisT_DESCRIPTION": "CHECKLIST 1"
                  },
                  {
                    "id": 2,
                    "checklisT_DESCRIPTION": "CHECKLIST 2"
                  },
                  {
                    "id": 3,
                    "checklisT_DESCRIPTION": "CHECKLIST 3"
                  }
                ]);
    
      useEffect(() => {
        axios.get("http://100.103.16.113:8081/api/checklists", {      
                      }).then
                       (function (response) {
                        setCheckList(response.data); // update the state
                      }).catch(error => {
                        console.log(error);                        
                      })
      }, [])
    
      return (
    

    【讨论】:

      【解决方案2】:

      您只需将回调保存在一个状态中,例如:

      ...
      
      const [checklist, setChecklist] = React.useState([]);
      useEffect(() => {
      axios.get("http://100.103.16.113:8081/api/checklists", {})
        .then
          (function (response) {
            setChecklist(response?.data);
          console.log(response.data);
        }).catch(error => {
          console.log(error);                        
        })
      }, []);
      ...
      

      为避免空指针异常,我建议您使用optional chaining 并阻止渲染,直到promise 得到解决。

      【讨论】:

      • @VinodSai 是的,标点符号很好。最后我的回答太肤浅了。谢谢!
      • 感谢您的解释和附加链接。
      【解决方案3】:

      您可以为checklists 创建一个状态变量,然后在useEffect 中使用axios.get 填充它。在映射列表并访问数据以呈现项目之前,请确保通过检查checklists.length 来验证清单是否已填充。

      const HomeScreen = ({ navigation }) => {
      
        // initialize the state variable
        const [checklists, setChecklists] = useState([]);
      
      
        // populate the data
        useEffect(() => {
         axios.get("http://100.103.16.113:8081/api/checklists")
               .then(function (response) {
                       setChecklists(response.data)
                    })
               .catch(error => {
                       console.log(error);                        
               })
        }, [])
      
        // when mapping over the checklists make sure you check for the checklists.length before mapping
      
        {checklists.length &&  checklists.map(r =>(
      
            <TouchableOpacity onPress = {() => navigation.navigate('AuditS')} 
               style={styles.button}    
            >
              <Image source={require('../assets/icons8-audit-80.png')} 
                style={styles.Image}>
              </Image>     
              <Text style={styles.ButtonText}>{r.checklisT_DESCRIPTION}</Text>
      
            </TouchableOpacity >
             ))}
      
      }
      
      

      这是一个例子codesandbox

      【讨论】:

      • 感谢您对代码的回答和 cmets,我根据您的方向更改了我的代码并且它正在工作。
      猜你喜欢
      • 1970-01-01
      • 2016-02-15
      • 2021-06-12
      • 1970-01-01
      • 1970-01-01
      • 2021-06-09
      • 2022-01-06
      • 2021-05-20
      • 1970-01-01
      相关资源
      最近更新 更多