Apify-Client having trouble working with React - reactjs

I hope you are having a fantastic day.
I am using this API: https://apify.com/petrpatek/covid-19-aggregator/api, for the first time, and I am having some issues getting it to work with React. This is the file where I am making my API call:
const ApifyClient = require('apify-client');
require('dotenv').config({ path: `${__dirname}/../../.env` });
const client = new ApifyClient({
token: process.env.REACT_APP_API_TOKEN,
});
const input = {};
const getItems = async () => {
// Run the actor and wait for it to finish
const run = await client.actor('petrpatek/covid-19-aggregator').call(input);
// Fetch and print actor results from the run's dataset (if any)
console.log('Results from dataset');
const { items } = await client.dataset(run.defaultDatasetId).listItems();
// console.log(items);
items.forEach((item) => {
console.dir(item);
});
return items;
};
getItems();
// export default getItems();
Most of the above is just copy-pasted from the API docs, this file has no problems running as a standalone, if I run node apify.js, it returns the correct data as I expect:
correct data
However when I try to run it inside of a React component, like so:
import { useEffect } from 'react';
import CountryCard from '../components/countryCard';
import Header from '../components/header';
import getItems from '../APIs/apify';
const AllCountriesPage = () => {
useEffect(() => {
getItems();
}, []);
return (
<div className="allCountriesPage">
<Header />
<CountryCard className="bannerCountry" />
<p className="allCountriesText">All countries</p>
<div className="allCountriesContainer">
{/* Some kind of for loop */}
<CountryCard />
</div>
</div>
);
};
export default AllCountriesPage;
It throws the following error:
error message
At first, I thought this was just a problem with the dependencies, but I do have them installed, or the file would not be running by itself, also this is my package.js file:
{
"name": "catalogue-of-statistics",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^5.11.4",
"#testing-library/react": "^11.1.0",
"#testing-library/user-event": "^12.1.10",
"apify-client": "^1.2.4",
"dotenv": "^8.2.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"web-vitals": "^1.0.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"#babel/core": "^7.14.5",
"#babel/eslint-parser": "^7.14.5",
"#babel/plugin-syntax-jsx": "^7.14.5",
"#babel/preset-react": "^7.14.5",
"eslint": "^7.28.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.24.0",
"eslint-plugin-react-hooks": "^4.2.0",
"stylelint": "^13.13.1",
"stylelint-config-standard": "^21.0.0",
"stylelint-csstree-validator": "^1.9.0",
"stylelint-scss": "^3.19.0"
}
}

I see my colleague replied to you over our Discord.
For others:
You need to add mainFields: ['browser', 'main', 'module'], to your webpack config. The order is important. main needs to go before module. See https://webpack.js.org/configuration/resolve/#resolvemainfields

As Lukas was saying above, the Apify team answered my question directly in their discord, so I want to put the solution here if someone comes across it in the future.
You need to go to node_modules -> react_scripts -> config -> webpack.config.js inside the resolve: { ... } object, add this line: mainFields: ['browser', 'main', 'module'], make sure that main is before module.

Related

Tailwind CSS is not showing the changes. [React + Tailwindcss]

I am in the middle of making an Instagram Clone SSR project using React and Tailwind.CSS but I got stuck with Tailwind CSS I have installed the required dependencies, changed scripts that was needed also added paths in tailwindcss.config.js, added #tailwind directives to the app.css file also but whatever is written in class names is not reflecting in the result after npm start
Login.js file for Login Page
import { useContext, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import FirebaseContext from "../context/firebase";
import "../styles/app.css";
export default function Login() {
const navigate = useNavigate();
const { firebase } = useContext(FirebaseContext);
const [emailAddress, setEmailAddress] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const isInvalid = password === "" || emailAddress === "";
const handleLogin = () => {};
useEffect(() => {
document.title = "Login - Instagram";
}, []);
return (
<div className='container flex mx-auto max-w-screen-md items-center h-screen'>
<div className='flex w-3/5'>
<img
src='/images/iphone-with-profile.jpg'
alt='iPhone with Instagram App'
className='max-w-full'
/>
</div>
<div className='flex flex-col w-2/5'>
<p>This is the Form</p>
</div>
</div>
);
}
package.json file - scripts and dependencies
{
"name": "instagram",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^5.16.5",
"#testing-library/react": "^13.4.0",
"#testing-library/user-event": "^13.5.0",
"date-fns": "^2.29.3",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-loading-skeleton": "^3.1.0",
"react-router-dom": "^6.8.1",
"react-scripts": "^5.0.1",
"web-vitals": "^3.1.1"
},
"scripts": {
"build:css": "postcss src/styles/tailwind.css -o src/styles/app.css",
"watch:css": "postcss src/styles/tailwind.css -o src/styles/app.css --watch",
"react-scripts:start": "react-scripts start",
"start": "run-p watch:css react-scripts:start",
"build": "run-s build:css react-scripts:build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"autoprefixer": "^10.4.13",
"babel-eslint": "^10.1.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-scope": "^7.1.1",
"npm-run-all": "^4.1.5",
"postcss": "^8.4.21",
"postcss-cli": "^10.1.0",
"postcss-loader": "^7.0.2",
"prettier": "^2.8.4",
"tailwindcss": "^3.2.6"
}
}
postcss.config.js
module.exports = {
plugins: [require("tailwindcss"), require("autoprefixer")],
};
tailwind.config.js
module.exports = {
future: {
removeDeprecatedGapUtilities: true,
},
theme: {
extend: {},
},
variants: {},
plugins: [],
content: ["./src/**/*.html", "./src/**/*.jsx", "./public/index.html"],
};
And in my app.css file the original file contained the "#tailwind" commands (base, utilities, components), but they were replaced with the generated CSS code that follows the defined styles in the Tailwind CSS configuration.
You should remove the curly braces in your classNames :
<div className='container flex mx-auto max-w-screen-md items-center h-screen'>
I think it's because your component's extension is .js but you don't have .js files covered in your Tailwind config (content property). I would recommend changing the extension of your component's file to .jsx.

renderHook causes `TooManyRerenders` error when changing state

I want to test a hook that uses states in its implementation, but each time I run my tests I get this error:
Error: Uncaught [Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.]
The hook is complex and I couldn't find which part may cause an issue (plus it works perfectly fine under real conditions, when running the application with npm start).
I tried to write a dummy test to see if I could figure out anything, and I found that updating a state (which I do in my hook) triggers the error.
Basically, this fails:
import { renderHook } from "#testing-library/react";
import React from "react";
it("foo test", () => {
const { result } = renderHook(() => {
const [foo, setFoo] = React.useState("foo");
setFoo("bar"); // This line is the culprit
return foo;
});
expect(result.current).toEqual("bar");
});
But this works:
import { renderHook } from "#testing-library/react";
import React from "react";
it("foo test", () => {
const { result } = renderHook(() => {
const [foo, setFoo] = React.useState("foo");
return foo;
});
expect(result.current).toEqual("foo");
});
What is the reason for this error and how can I fix it ?
Also, my package.json file:
{
"name": "agora-front",
"version": "0.1.0",
"private": true,
"dependencies": {
"#emotion/react": "^11.10.0",
"#emotion/styled": "^11.10.0",
"#mui/icons-material": "^5.8.4",
"#mui/material": "^5.9.3",
"#testing-library/jest-dom": "^5.16.4",
"#testing-library/react": "^13.3.0",
"#types/react": "^18.0.15",
"#types/react-dom": "^18.0.6",
"i18next": "^21.8.16",
"i18next-browser-languagedetector": "^6.1.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^11.18.3",
"react-router-dom": "^6.3.0",
"react-scripts": "5.0.1",
"typescript": "^4.7.4",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "BROWSER=none react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --verbose",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"#babel/preset-typescript": "^7.18.6",
"#types/jest": "^28.1.6",
"jest": "^28.1.3",
"prettier": "2.7.1",
"react-test-renderer": "^18.2.0"
}
}
I got tricked by the test environment and forgot React basic good practices.
Every state update should be wrapped in a condition with useEffect, otherwise render will trigger endlessly.
I followed that practice in all my React components, thus explaining why it was working fine when building the application. But I wrote my tests a bit quickly.
For my quick example, this is the correct way to do it:
import { renderHook } from "#testing-library/react";
import React from "react";
it("foo test", () => {
const { result } = renderHook(() => {
const [foo, setFoo] = React.useState("foo");
React.useEffect(() => {
setFoo("bar"); // Now it works.
}, [])
return foo;
});
expect(result.current).toEqual("bar");
});

Cypress returns "browserslist" error in Create React App?

I've got a very simple Create React App that I am trying to implement Cypress with. I initially had a different but related error that I was able to overcome. I'm not entirely sure why I would be given this type of error considering I do have the default "browserslist" key in my package.json file.
package.json
{
"name": "cypress_test",
"version": "0.1.0",
"private": true,
"engines": {
"node": "16.13.1",
"npm": "8.1.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"cypress": "cypress open",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"dependencies": {
"#cypress/react": "^5.12.4",
"#cypress/webpack-dev-server": "^1.8.4",
"#emotion/react": "^11.9.0",
"#emotion/styled": "^11.8.1",
"#fontsource/roboto": "^4.5.5",
"#mui/icons-material": "^5.6.2",
"#mui/material": "^5.6.3",
"#mui/styled-engine-sc": "^5.6.1",
"#testing-library/jest-dom": "^5.16.4",
"#testing-library/react": "^12.1.5",
"#testing-library/user-event": "^13.5.0",
"browserslist": "^4.6.3",
"cypress": "^9.6.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.1",
"sass": "^1.51.0",
"styled-components": "^5.3.5",
"web-vitals": "^2.1.4"
},
"devDependencies": {
"#babel/core": "^7.17.9",
"#babel/preset-env": "^7.16.11",
"#cypress/webpack-preprocessor": "^5.11.1",
"babel-loader": "^8.2.5",
"eslint-plugin-cypress": "^2.12.1",
"html-webpack-plugin": "^4.5.2",
"webpack": "^5.72.0"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"overrides": [
{
"extends": [
"plugin:cypress/recommended"
],
"files": [
"cypress/**/*.js"
]
}
],
"resolutions": {
"#mui/styled-engine": "npm:#mui/styled-engine-sc#latest"
},
"jest": {
"coveragePathIgnorePatterns": [
"<rootDir>/cypress/"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
When I initially installed CRA, it used the latest version of React 18, but apparently Cypress doesn't have support for 18 yet so I downgraded React to 17. I'm wondering if there are some sort of package mismatches that I'm unaware of and aren't receiving specific errors for. As a note though, the app runs fine in the browser. Here are the other related files:
/cypress/plugins/index.js:
const findWebpack = require('find-webpack')
const webpackPreprocessor = require('#cypress/webpack-preprocessor');
const injectDevServer = require('#cypress/react/plugins/react-scripts');
module.exports = (on, config) => {
const webpackOptions = findWebpack.getWebpackOptions();
if (!webpackOptions) {
throw new Error('Could not find Webpack in this project');
}
const cleanOptions = { reactScripts: true };
findWebpack.cleanForCypress(cleanOptions, webpackOptions);
const options = {
webpackOptions,
watchOptions: {},
};
on('file:preprocessor', webpackPreprocessor(options));
injectDevServer(on, config);
return config;
};
App.spec.js:
import React from 'react';
import data from '../fixtures/data.json';
import App from '../../src/App.jsx';
describe('Test search functionality', () => {
beforeEach(() => {
cy.mount(<App />);
});
it('renders new fact when search is performed', () => {
cy.visit('http://localhost:3001')
// Type in search input
cy.get('input').type('Test');
// Click on search button
cy.get('.submit-btn').click();
// Intercept the request and return the mock data
cy
.intercept({
method: 'GET',
url: `${process.env.REACT_APP_API_ENDPOINT}/jokes/search?query=Test`
}, {
fixture: data.result[1]
})
.as('fetchFact');
// cy.wait(['#fetchFact']);
cy.get('p.copy').should('contain', data.result[1].value);
})
});
cypress.json:
{
"baseUrl": "http://localhost:3001",
"videos": false,
"component": {
"testFiles": "**/*.cy.{js,ts,jsx,tsx}",
"componentFolder": "src"
}
}
Cypress error:
Error: No browserslist config found to handle the 'browserslist' target.
See https://github.com/browserslist/browserslist#queries for possible ways to provide a config.
The recommended way is to add a 'browserslist' key to your package.json and list supported browsers (resp. node.js versions).
You can also more options via the 'target' option: 'browserslist' / 'browserslist:env' / 'browserslist:query' / 'browserslist:path-to-config' / 'browserslist:path-to-config:env'
at TARGETS.web (/Users/jimmiejackson/Documents/repositories/cypress_test/node_modules/webpack/lib/config/target.js:93:11)
at getTargetProperties (/Users/jimmiejackson/Documents/repositories/cypress_test/node_modules/webpack/lib/config/target.js:296:19)
at /Users/jimmiejackson/Documents/repositories/cypress_test/node_modules/webpack/lib/config/target.js:342:20
at Array.map (<anonymous>)
at getTargetsProperties (/Users/jimmiejackson/Documents/repositories/cypress_test/node_modules/webpack/lib/config/target.js:342:11)
at applyWebpackOptionsDefaults (/Users/jimmiejackson/Documents/repositories/cypress_test/node_modules/webpack/lib/config/defaults.js:142:6)
at createCompiler (/Users/jimmiejackson/Documents/repositories/cypress_test/node_modules/webpack/lib/webpack.js:77:2)
at create (/Users/jimmiejackson/Documents/repositories/cypress_test/node_modules/webpack/lib/webpack.js:134:16)
at webpack (/Users/jimmiejackson/Documents/repositories/cypress_test/node_modules/webpack/lib/webpack.js:158:32)
at f (/Users/jimmiejackson/Documents/repositories/cypress_test/node_modules/webpack/lib/index.js:63:16)
at Object.handler (/Users/jimmiejackson/Documents/repositories/cypress_test/node_modules/#cypress/webpack-preprocessor/dist/index.js:148:24)
at invoke (/Users/jimmiejackson/Library/Caches/Cypress/9.6.0/Cypress.app/Contents/Resources/app/packages/server/lib/plugins/child/run_plugins.js:22:16)
at /Users/jimmiejackson/Library/Caches/Cypress/9.6.0/Cypress.app/Contents/Resources/app/packages/server/lib/plugins/util.js:45:14
at tryCatcher (/Users/jimmiejackson/Library/Caches/Cypress/9.6.0/Cypress.app/Contents/Resources/app/packages/server/node_modules/bluebird/js/release/util.js:16:23)
at Function.Promise.attempt.Promise.try (/Users/jimmiejackson/Library/Caches/Cypress/9.6.0/Cypress.app/Contents/Resources/app/packages/server/node_modules/bluebird/js/release/method.js:39:29)
at Object.wrapChildPromise (/Users/jimmiejackson/Library/Caches/Cypress/9.6.0/Cypress.app/Contents/Resources/app/packages/server/lib/plugins/util.js:44:23)
at Object.wrap (/Users/jimmiejackson/Library/Caches/Cypress/9.6.0/Cypress.app/Contents/Resources/app/packages/server/lib/plugins/child/preprocessor.js:28:8)
at execute (/Users/jimmiejackson/Library/Caches/Cypress/9.6.0/Cypress.app/Contents/Resources/app/packages/server/lib/plugins/child/run_plugins.js:123:27)
at EventEmitter.<anonymous> (/Users/jimmiejackson/Library/Caches/Cypress/9.6.0/Cypress.app/Contents/Resources/app/packages/server/lib/plugins/child/run_plugins.js:213:5)
at EventEmitter.emit (node:events:390:28)
at process.<anonymous> (/Users/jimmiejackson/Library/Caches/Cypress/9.6.0/Cypress.app/Contents/Resources/app/packages/server/lib/plugins/util.js:19:22)
at process.emit (node:events:390:28)

'useState' is defined but never used EVENTHOUGH I have used useState hook

I have simple functional component like below.
import React, { useState } from 'react';
import { connect } from 'react-redux';
import JoinRoomInputs from '../../../components/JoinRoomPage/JoinRoomInputs/JoinRoomInputs';
import { State } from '../../../store/states/states';
interface Props {
isRoomHost: boolean;
}
const JoinRoomContent = ({ isRoomHost }:Props) => {
const [roomIdValue, setRoomIdValue] = useState('');
const [nameValue, setNameValue] = useState('');
return (
<>
<JoinRoomInputs roomIdValue={roomIdValue} setRoomIdValue={setRoomIdValue} nameValue={nameValue} setNameValue={setNameValue} isRoomHost={isRoomHost} />
</>
);
};
const mapStateToProps = (state:State) => {
return {
...state
}
}
export default connect(mapStateToProps)(JoinRoomContent);
as you can see I have used useState hook in two lines.
But I'm getting yellow warning saying this.
src\components\JoinRoomPage\JoinRoomContent\JoinRoomContent.tsx
Line 1:17: 'useState' is defined but never used #typescript-eslint/no-unused-vars
Search for the keywords to learn more about each warning.
To ignore, add // eslint-disable-next-line to the line before.
And what is more curious is line 17 is this );
This doesn't make any sense to me.
What am I doing wrong here ?
below is my package.json
{
"name": "client",
"version": "0.1.0",
"private": true,
"dependencies": {
"#reduxjs/toolkit": "^1.6.2",
"#testing-library/jest-dom": "^4.2.4",
"#testing-library/react": "^9.5.0",
"#testing-library/user-event": "^7.2.1",
"#types/jest": "^24.9.1",
"#types/node": "^12.20.36",
"#types/react": "^16.14.20",
"#types/react-dom": "^16.9.14",
"#types/react-redux": "^7.1.20",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-redux": "^7.2.6",
"react-router-dom": "^6.0.2",
"react-scripts": "4.0.3",
"typescript": "^4.1.6"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"typescript-plugin-css-modules": "^3.4.0"
}
}
Restart your server or kill the port with the following command:
sudo kill $(sudo lsof -t -i:PORT)

React-Redux: Cannot read property 'closed' of undefined

I seem to have run into an issue when using dispatch() with React-Redux. For example, the following action:
export const fetchMetrics = () => {
dispatch(fetchMetricsBegin);
APIService.get('/dashboard/info/')
.then((response) => {
dispatch(fetchMetricsSuccess(response));
return response;
})
.catch(error => dispatch(fetchMetricsFailure(error)));
};
Produces the following error:
TypeError: Cannot read property 'closed' of undefineddispatch
src/internal/observable/pairs.ts:82
Here's my package.json:
{
"name": "app",
"version": "0.1.0",
"private": true,
"dependencies": {
"#popperjs/core": "^2.6.0",
"#testing-library/jest-dom": "^5.11.6",
"#testing-library/react": "^11.2.2",
"#testing-library/user-event": "^12.6.0",
"axios": "^0.21.0",
"dotenv": "^8.2.0",
"jwt-decode": "^3.1.2",
"react": "^17.0.1",
"react-datepicker": "^3.3.0",
"react-dom": "^17.0.1",
"react-images-upload": "^1.2.8",
"react-number-format": "^4.4.1",
"react-popper": "^2.2.4",
"react-redux": "^7.2.2",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.1",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"rxjs": "^6.6.3",
"web-vitals": "^0.2.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
I have tried purging node_module and package-lock.json, but the issue is still occurring. Would welcome any insight. Removing the dispatch calls removes the error.
you are using redux-thunk. this library will allow you to perform async calls since your function return another function with dispatch as param. otherwise thunk will execute the code sync.
export const fetchMetrics = () => (dispatch) => {
dispatch(fetchMetricsBegin);
APIService.get('/dashboard/info/')
.then((response) => {
dispatch(fetchMetricsSuccess(response));
return response;
})
.catch(error => dispatch(fetchMetricsFailure(error)));
};

Resources