【问题标题】:Why is data fetched from API using react-hook provided inconsistently?为什么使用 react-hook 从 API 获取的数据不一致?
【发布时间】:2020-09-10 09:03:43
【问题描述】:

我正在尝试使用 React-hook 呈现一些名称字符串。数据是从控制器文件中定义的“/api/getMoreCards”端点获取的,并且工作正常。

问题在于,当我将获取的数据存储到 react-hook 的 useState 对象的“数据”中时,它会不一致地访问数据。让我更具体一点:

import React, {useState, useEffect} from 'react';
import axios from 'axios';
const regeneratorRuntime = require("regenerator-runtime");

const HS = () => {
  const getData = async() => {
    const data = await axios.get('/api/getMoreCards')
    console.log(data)
    setData(data)
}
  const [data, setData] = useState({});
    useEffect(()=>{
      getData()
    },[]);

    return (
      <div>
        <h1>List of Cards</h1>
        **<div>{data.data[0].name}</div>**
      </div>
    );
}
export default HS;

这个文件被导出到 App.js。

在上面的代码中,data.data[0].name 有时会在本地主机上正确呈现,但大多数时候,它会给我以下错误:

“未捕获的类型错误:无法读取未定义的属性'0' 在控制台上的 HS (hsContainer.js:76)"。

在这种情况下,第 7 行的控制台登录根本不会出现在控制台中。

我试过关闭再重新打开VScode,把文件改成'jsx',把data.data[0].name声明为常量,改变getData和useState代码的顺序,还是不一致。

这是我的 webpack.config.js 和 package.json 文件供参考:

Webpack.config.js

const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const config = {
  entry: [
    'react-hot-loader/patch',
    './src/index.js'
  ],
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  mode: process.env.NODE_ENV,
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: 'babel-loader',
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader'
        ]
      },
      {
        test: /\.svg$/,
        use: 'file-loader'
      },
      {
        test: /\.png$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              mimetype: 'image/png'
            }
          }
        ]
      }
    ]
  },
  resolve: {
    extensions: [
      '.js',
      '.jsx'
    ],
    alias: {
      'react-dom': '@hot-loader/react-dom'
    }
  },
  devServer: {
        contentBase: './dist',
        proxy: {
            '/api': 'http://localhost:3000',
            '/api/profile': 'http://localhost:3000',
        },
        historyApiFallback: true,
    },
  plugins: [
    new HtmlWebpackPlugin({
        template: `./public/index.html`,
    }),
  ],
};

module.exports = config;

package.json

{
  "name": "Solo-Project",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node ./server/server.js",
    "build": "cross-env NODE_ENV=production webpack",
    "devother": "cross-env NODE_ENV=development webpack-dev-server --open --hot & nodemon ./server/server.js",
    "dev": "concurrently \"cross-env NODE_ENV=development webpack-dev-server --open --hot --inline --progress --colors --watch --content-base ./\" \"nodemon ./server/server.js\""
  },
  "repository": {
    "type": "git",
    "url": "git+https://I have replaced this for privacy on stackoverflow.git"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "https://I have replaced this for privacy on stackoverflow"
  },
  "homepage": "https://I have replaced this for privacy on stackoverflow",
  "devDependencies": {
    "@babel/core": "^7.11.6",
    "@babel/preset-env": "^7.11.5",
    "@babel/preset-react": "^7.10.4",
    "@hot-loader/react-dom": "^16.13.0",
    "babel-loader": "^8.1.0",
    "css-loader": "^4.3.0",
    "file-loader": "^6.1.0",
    "html-webpack-plugin": "^4.4.1",
    "style-loader": "^1.2.1",
    "url-loader": "^4.1.0",
    "webpack": "^4.44.1",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0"
  },
  "dependencies": {
    "axios": "^0.20.0",
    "concurrently": "^5.3.0",
    "cross-env": "^7.0.2",
    "express": "^4.17.1",
    "nodemon": "^2.0.4",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-hot-loader": "^4.12.21"
  }
}

【问题讨论】:

    标签: get axios react-hooks


    【解决方案1】:

    当您访问数据时,数据中没有任何内容。要么用一个包含元素的数组来初始化它,要么在渲染之前检查数组是否为空。

    const [data, setData] = useState({
        data: [{
            name: "tmp"
        }]
    });
    
    // or with optional chaining
    
    return (
        <div> <h1>List of Cards</h1>
           {data?.data?.length && (
                <div>{data.data[0].name}</div>
           )}
        </div>
    );
    

    【讨论】:

      【解决方案2】:

      也可以在渲染前先检查“数据”是否有效

      <div>{data && data.data[0].name}</div>
      

      【讨论】:

        猜你喜欢
        • 2019-11-24
        • 1970-01-01
        • 2019-09-16
        • 2021-04-22
        • 2022-07-12
        • 1970-01-01
        • 2021-09-26
        • 2021-04-26
        • 2020-03-10
        相关资源
        最近更新 更多