Reputation: 159
I am trying to render some string of names using React-hook. The data is fetched from the '/api/getMoreCards' end point, which is defined in the controller file, and works fine.
The problem is that when I store the fetched data into 'data' of react-hook's useState object, it inconsistently gives access to the data. Let me be more specific:
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;
This file is exported into App.js.
In the above code, the data.data[0].name
is sometimes rendered on the localhost correctly, but most of the times, it gives me the error of:
"Uncaught TypeError: Cannot read property '0' of undefined at HS (hsContainer.js:76)" on the console.
In this case, the console logging on line 7 does not appear in the console at all.
I have tried closing and reopening VScode, changing the file to 'jsx', declared the data.data[0].name
as a constant, changing the order of getData and useState codes, all of which were still inconsistent.
Here are my webpack.config.js and package.json file for reference:
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"
}
}
Upvotes: 0
Views: 38
Reputation: 396
You can also check if "data" is valid first before rendering
<div>{data && data.data[0].name}</div>
Upvotes: 0
Reputation: 26877
There is nothing in data whenever you are accessing it. Either initialize it with an array that has an element or check if the array is empty before rendering.
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>
);
Upvotes: 1