【问题标题】:Receiving JSON Data from a server and storing it in an array从服务器接收 JSON 数据并将其存储在数组中
【发布时间】:2021-04-07 05:09:12
【问题描述】:

我正在创建一个带有类似 tinder 的 UI 的 React Native 应用程序。尽管它应该显示视频游戏封面,而不是显示用户。我有我的 nodejs 服务器设置,我可以通过邮递员从它接收信息。 在 http://localhost:9000/coverInfo 向我的服务器发送 get 请求后, 我得到这个 json 作为响应:

[
    {
        "id": 110592,
        "alpha_channel": false,
        "animated": false,
        "game": 96367,
        "height": 800,
        "image_id": "co2dc0",
        "url": "//images.igdb.com/igdb/image/upload/t_thumb/co2dc0.jpg",
        "width": 800,
        "checksum": "04a45b3f-4f90-f4a1-cc0d-1483f0cc2612"
    },
    {
        "id": 65483,
        "game": 100547,
        "height": 800,
        "image_id": "pkkd08qhfxt5cosp3hra",
        "url": "//images.igdb.com/igdb/image/upload/t_thumb/pkkd08qhfxt5cosp3hra.jpg",
        "width": 1260,
        "checksum": "e09f916b-04fe-8993-594e-b18435438a35"
    },
    {
        "id": 96891,
        "alpha_channel": false,
        "animated": false,
        "game": 132099,
        "height": 933,
        "image_id": "co22rf",
        "url": "//images.igdb.com/igdb/image/upload/t_thumb/co22rf.jpg",
        "width": 700,
        "checksum": "2452703f-4092-bb6f-d52c-51eb30a4ab94"
    },
....

从客户端,我试图检索这些数据并将其存储在一个数组中。这是我的代码在客户端的样子:

export default function App() {

   const [games, setGames] = useState([])
   const [currentIndex, setCurrentIndex] = useState(0)
   const swipesRef = useRef(null)
   
   async function fetchGames() {
      try {
         const {data} = await axios.get('http://localhost:9000/coverInfo')
         setGames(data.results)
         console.log(data.results)
     }   catch (error) {
         console.log
         Alert.alert('Error getting games', '', [{text: 'Retry', onPress: () => fetchGames()}])
   }
}


   useEffect(() => {
      fetchGames()
   }, [])

   function handleLike() {
      console.log('like')
      nextGame()
   }

   function handlePass() {
      console.log('pass')
      nextGame()
   }

   function nextGame() {
      const nextIndex = games.length - 2 == currentIndex ? 0 : currentIndex + 1
      setCurrentIndex(nextIndex)
   }

   function handleLikePress() {
      swipesRef.current.openLeft()
   }

   function handlePassPress(){
      swipesRef.current.openRight()
   }

   return (
     <View style={styles.container}>
        <TopBar />
         <View style = {styles.swipes}>
            {games.length > 1 &&
               games.map(
                  (u, i) =>
                  currentIndex == i && (
                  <Swipes 
                     key = {i} 
                     ref={swipesRef} 
                     currentIndex={currentIndex} 
                     games={games} 
                     handleLike={handleLike} 
                     handlePass={handlePass}
                  ></Swipes>
                  )
               )}
         </View>
         <BottomBar handlePassPress={handlePassPress} handleLikePress={handleLikePress}/>
     </View>
   );
 }

但是,运行时出现以下错误:

TypeError: Cannot read property 'length' of undefined
App
C:/Users/matth/Joystik/App.js:62
  59 | return (
  60 |   <View style={styles.container}>
  61 |      <TopBar />
> 62 |       <View style = {styles.swipes}>
     | ^  63 |          {games.length > 1 &&
  64 |             games.map(
  65 |                (u, i) =>
View compiled
▶ 17 stack frames were collapsed.
fetchGames$
C:/Users/matth/Joystik/App.js:23
  20 | async function fetchGames() {
  21 |    try {
  22 |       const {data} = await axios.get('http://localhost:9000/coverInfo')
> 23 |       setGames(data.results)
     | ^  24 |       console.log(data.results)
  25 |   }   catch (error) {
  26 |       console.log
View compiled
▶ 6 stack frames were collapsed.

我服务器端的代码如下所示:

router.get("/", function(req, res, next) {

    axios({
        url: "https://api.igdb.com/v4/covers",
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Client-ID' : '----------------------------',
            'Authorization' : 'Bearer ------------------',
        },
        data: "fields alpha_channel,animated,checksum,game,height,image_id,url,width;"
      })
      .then(response => {
        //console.log(response.data);
        const testing = response.data;
        res.json(testing);
        })
    .catch(err => {
        console.error(err);
        });
    
    
});

我尝试将“data.results”更改为仅数据,但它不起作用。客户端没有从节点 js 服务器获得任何东西。

还可以注意到,我能够成功接收来自另一个客户端项目的信息,如下所示:

class App extends React.Component{

  
  constructor(props){
    super(props);
    this.state = {apiResponse: ""};
  }

  callAPI() {
    fetch("http://localhost:9000/coverInfo")
    .then(res => res.text())
    //.then(res => console.log(res.json))
    .then(res => this.setState({apiResponse: res}));
  }
  componentWillMount(){
    this.callAPI();
  }

render(){
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
      </header>
      <p>
        {this.state.apiResponse}
      </p>
    </div>
  );
}
}
export default App;

这会在网页底部返回以下文本:

[{"id":110592,"alpha_channel":false,"animated":false,"game":96367,"height":800,"image_id":"co2dc0","url":"//images.igdb.com/igdb/image/upload/t_thumb/co2dc0.jpg","width":800,"checksum":"04a45b3f-4f90-f4a1-cc0d-1483f0cc2612"},{"id":65483,"game":100547,"height":800,"image_id":"pkkd08qhfxt5cosp3hra","url":"//images.igdb.com/igdb/image/upload/t_thumb/pkkd08qhfxt5cosp3hra.jpg","width":1260,"checksum":"e09f916b-04fe-8993-594e-b18435438a35"},{"id":96891,"alpha_channel":false,"animated":false,"game":132099,"height":933,"image_id":"co22rf","url":"//images.igdb.com/igdb/image/upload/t_thumb/co22rf.jpg","width":700,"checksum":"2452703f-4092-bb6f-d52c-51eb30a4ab94"},{"id":9331,"game":8938,"height":750,"image_id":"ikjcylxero1pb1sl9clj","url":"//images.igdb.com/igdb/image/upload/t_thumb/ikjcylxero1pb1sl9clj.jpg","width":640,"checksum":"0519ea95-feda-c674-1e6a-88a388ba5899"},{"id":900,"game":194,"height":362,"image_id":"fl0bjezupibkettkmsyg","url":"//images.igdb.com/igdb/image/upload/t_thumb/fl0bjezupibkettkmsyg.jpg","width":300,"checksum":"ffbf4f5b-99b9-eab3-1eb6-ea7f4f9c2df1"},{"id":28001,"game":46426,"height":2156,"image_id":"arzwj3bju1aoakgufnku","url":"//images.igdb.com/igdb/image/upload/t_thumb/arzwj3bju1aoakgufnku.jpg","width":1539,"checksum":"fb9fae9b-d717-d1d1-a3ee-ef6191af168d"},{"id":6424,"game":2410,"height":150,"image_id":"y7otr2cfclfpfuhtzhzq","url":"//images.igdb.com/igdb/image/upload/t_thumb/y7otr2cfclfpfuhtzhzq.jpg","width":342,"checksum":"d41815d5-85a7-ac17-c067-ac88563578e9"},{"id":15242,"game":18896,"height":360,"image_id":"dq7tvq2dub1xj0jnqafe","url":"//images.igdb.com/igdb/image/upload/t_thumb/dq7tvq2dub1xj0jnqafe.jpg","width":480,"checksum":"35bd8f63-6766-5426-d7c2-aaa34e8d8a19"},{"id":6432,"game":6264,"height":341,"image_id":"rii076tdl6uy1tnhohsg","url":"//images.igdb.com/igdb/image/upload/t_thumb/rii076tdl6uy1tnhohsg.jpg","width":500,"checksum":"f48c9e58-b52f-382b-9d92-4031e5a5a15c"},{"id":27255,"game":48063,"height":2100,"image_id":"unmgn234f5uesld8nfcn","url":"//images.igdb.com/igdb/image/upload/t_thumb/unmgn234f5uesld8nfcn.jpg","width":1528,"checksum":"fec3c3a3-6edd-5a35-5440-f1a19455a9

【问题讨论】:

  • 试试这样:{games?.length > 1 && games.map(......
  • 是.that data.result 一个数组吗?还是一个物体?
  • data.result 应该是一个对象
  • 它接缝 data.results 未定义。请在将 data.results 的值传递给 setGames 函数之前检查它的值。
  • 您在 console.log(data.results) 中获得了什么价值?你能分享一下你在代码中得到的确切值吗?

标签: json react-native api


【解决方案1】:

如果可能,查看您的服务器端代码会很有帮助。导致看到你的 服务器响应我认为你应该只使用data 而不是data.results 因为你提供的 JSON 只是数据并且没有其他对象(我在这里的术语可能是错误的)。

因为使用 data.results 你应该有:

 {
        "results": [{
            "id": 110592,
            "alpha_channel": false,
            "animated": false,
            "game": 96367,
            "height": 800,
            "image_id": "co2dc0",
            "url": "//images.igdb.com/igdb/image/upload/t_thumb/co2dc0.jpg",
            "width": 800,
            "checksum": "04a45b3f-4f90-f4a1-cc0d-1483f0cc2612"
        }, {
            "id": 65483,
            "game": 100547,
            "height": 800,
            "image_id": "pkkd08qhfxt5cosp3hra",
            "url": "//images.igdb.com/igdb/image/upload/t_thumb/pkkd08qhfxt5cosp3hra.jpg",
            "width": 1260,
            "checksum": "e09f916b-04fe-8993-594e-b18435438a35"
        }]
    }

您指定控制台的评论没有记录任何内容,这让我对自己的回答更有信心

这是你可以用来使用data.results的代码(假设你正在使用nodeJS)

res.send({results: yourjsondata}).status(200)

为了避免您的应用在没有数据的情况下不断崩溃(生产环境中的良好做法)。

        const {data} = await axios.get('http://localhost:9000/coverInfo')
        if(data.results){
          setGames(data.results)
          console.log(data.results)
        }else{
          console.error("No data received from server")
  

【讨论】:

  • 感谢您的回复!我将 catch 块更改为 if 语句,运行时出现此错误: [Unhandled promise reject: Error: Network Error] at node_modules\axios\lib\core\createError.js:15:17 in createError 我尝试仅使用“数据" 而不是 data.results 但什么都没有。 Web 控制台说“没有从服务器收到数据”我在最初的帖子中包含了我的服务器端代码
  • 能否为您在服务器端接收的数据提供控制台日志?
  • 和我提供的用于阻止它崩溃的代码示例,您可以将 games.length&gt;1 更改为 games
  • 所以当我 console.log 服务器端时,我得到 [ { id: 110592, alpha_channel: false, animated: false, game: 96367, height: 800, image_id: 'co2dc0', url: '//images.igdb.com/igdb/image/upload/t_thumb/co2dc0.jpg', width: 800, checksum: '04a45b3f-4f90-f4a1-cc0d-1483f0cc2612' }, (基本上是预期的输出)
【解决方案2】:

我能够通过不使用 localhost 作为 url 来使其工作,因为它没有加载到 android 模拟器上。 我使用的代码如下所示:

 async function fetchGames() {
         try {
            const {data} = await axios.get('http://10.0.2.2:9000/coverInfo')
            //console.log("ata", data)
            setGames(data)
         }  catch (error) {
            console.log("error", error)
            Alert.alert('Error getting users', '', [{text: 'Retry', onPress: () => fetchGames()}])
      }
   }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-15
    • 2017-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多