How to test values that can depend on current localization?
function DateNavigation({ locale, date }) {
return (locale === 'en')
? <span>{moment(date).format('DD.MM.YYYY')}</span>
: <span>{moment(date).format('YYYY.MM.DD')}</span>
}
This test doesn't work sometimes because of locations
it('display date correctly', () => {
const component = mount(<DateNavigation date={'2022-01-31'} />);
expect(component.html()).toEqual("<span>31.01.2022</span>");
});
You can use jest.mock(moduleName, factory, options) to mock moment(), moment().format() functions and its returned value. Test results must be predictable. For the test about date, we need to make the test case return a certain value in different systems, time zones and localization.
E.g.
DateNavigation.jsx:
import React from 'react';
import moment from 'moment';
function DateNavigation({ locale, date }) {
return locale === 'en' ? (
<span>{moment(date).format('DD.MM.YYYY')}</span>
) : (
<span>{moment(date).format('YYYY.MM.DD')}</span>
);
}
export default DateNavigation;
DateNavigation.test.jsx:
import DateNavigation from './DateNavigation';
import moment from 'moment';
jest.mock('moment', () => {
const mMoment = { format: jest.fn() };
return jest.fn(() => mMoment);
});
describe('62042433', () => {
it('display date correctly', () => {
const date = '31.01.2022';
moment().format.mockReturnValueOnce(date);
const component = mount(<DateNavigation date={'2022-01-31'} locale={'en'} />);
expect(component.html()).toEqual('<span>31.01.2022</span>');
expect(moment).toBeCalledWith('2022-01-31');
expect(moment().format).toBeCalledWith('DD.MM.YYYY');
});
});
unit test results:
PASS stackoverflow/62042433/DateNavigation.test.jsx (13.544s)
62042433
✓ display date correctly (54ms)
--------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
--------------------|---------|----------|---------|---------|-------------------
All files | 100 | 50 | 100 | 100 |
DateNavigation.jsx | 100 | 50 | 100 | 100 | 6
--------------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 15.23s
Related
I have a React app, and I'm trying to build out some unit tests.
I got most of this test working, but I still can't figure out how to test one line using jest. I can't tell if it's because of the package I imported or if I'm doing something else incorrectly.
LogOutForDisagreement.js
import React from 'react';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import ClipboardClip from './../ClipboardClip';
const store = require('store2');
function LogOutForDisagreement(props) {
const handleClick = (e) => {
e.preventDefault();
props.onChange(
props.props.user = {
loggedIn: false,
email: '',
password: '',
firstName: ''
},
);
store.clearAll();
//sessionStorage.clear();
};
return (
<div id="logOutForDisagreementClipboard" className={props.className}>
<Form className="form">
<ClipboardClip />
<div className="centeredPaper">
<p>Sorry, you must agree to our privacy policy to access the site. You must now log out and log back in to agree to the terms.</p>
<Button id="logOutForDisagreement" type="" onClick={handleClick}>
Log Out
</Button>
</div>
</Form>
</div>
);
}
export default LogOutForDisagreement;
LogOutForDisagreement.test.js
import React from 'react';
import { render, fireEvent, cleanup } from '#testing-library/react';
import toJson from 'enzyme-to-json';
import LogOutForDisagreement from './LogOutForDisagreement';
const store = require('store2');
let props = {
props:
{
user: {
loggedIn: false,
email: 'email#example.com',
password: '0cc3dd4ad221f83270f876908064fa67d43407aa4bd580731b30c58c4fe2d8de00464107e5a143594068461af21ece9fb542e2f254b6f895eea6a6627f4f7c438a42fb18af7f539c4be2456661a5beec4a561f9443988182445b3952a5d9321a2d725b24b151f79a2806432c848b0b0c02576676e3a5c6f0661b4e318ca4f3e134d066808fab8fdd5322ed5cf5ad68aae43254a8fefdb69809c1bfdc07fe0365f38baa424d0c059c3a9fbff1f3525dae410740b9719929ef3f34235da519591f0410a08438132600fa802079b8d6f372f6dc439eb1b100aed28bb55cc3c6dc8982644940bd506278943fa8e430836cb874283e9f4438aac04a817f86bd1606036f03d196a211bdd91ac683d4ec63fcd503aa97b53d5c2571d39855b2be5f77be80a7f767271c8789aec26c66530c22387007c704f96b1a76a47e8e13fb263a0a6b24b2959495d34b47e03bcb95e8af13b555c5c403ec01427182afa1bae35ff81224b051fde7a61bd9044ed74042444a05e06186eedacc38c0128ff7d70c',
firstName: 'FirstName'
},
className: "logOutForDisagreement"
}
};
//You don't need the props for everything, just the className, but I'm leaving them here for now.
describe('Test the log out for disagreement button', () => {
it('renders correctly enzyme and has onclick', async () => {
console.log("This is the store at the begining after initial load: {" + Object.entries(sessionStorage).map(([key, val] = sessionItem) => {
return `${key}: ${val}`}) + "}");
const { getByText } = render(<LogOutForDisagreement id="logOutForDisagreementClipboard" className={props.className} />);
const spy = jest.spyOn(store, 'clearAll');
await fireEvent.click(getByText("Log Out"));
console.log("This is in the store after the event fires: {" + Object.entries(sessionStorage).map(([key, val] = sessionItem) => {
return `${key}: ${val}`}) + "}");
expect(spy).toHaveBeenCalled();
expect(toJson(getByText)).toMatchSnapshot();
//spy.mockRestore();
});
});
I still get an error that says the following:
Test the log out for disagreement button › renders correctly enzyme and has onclick
expect(jest.fn()).toHaveBeenCalled()
Expected number of calls: >= 1
Received number of calls: 0
37 | return `${key}: ${val}`}) + "}");
38 |
> 39 | expect(spy).toHaveBeenCalled();
| ^
40 |
41 | expect(toJson(getByText)).toMatchSnapshot();
42 | //spy.mockRestore();
...
--------------------------------------------|---------|----------|---------|---------|----------------------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
--------------------------------------------|---------|----------|---------|---------|--------------------
...
LogOutForDisagreement.js | 83.33 | 100 | 100 | 83.33 | 19
I'm just missing one line. Does anyone know how to get 100% test coverage on this? I know this is picky, but I use this same package in a lot of places.
I'm just posting the answer for anyone who runs into a similar issue. I used a tutorial from youtube.com that also used a third party library (axios) and mocked the built in axios functions: https://www.youtube.com/watch?v=gA-uNj2FgdM. I also had to pass the props down to the component and include onChange in the component, but now I have 100% test coverage.
LogOutForDisagreement.test.js
import React from 'react';
import { render, fireEvent, cleanup, screen } from '#testing-library/react';
import toJson from 'enzyme-to-json';
import LogOutForDisagreement from './LogOutForDisagreement';
import mockStore from 'store2';
jest.mock('store2');
mockStore.clearAll(() => Promise.resolve({}));
let props = {
props:
{
user: {
loggedIn: false,
email: 'email#example.com',
password:'0cc3dd4ad221f83270f876908064fa67d43407aa4bd580731b30c58c4fe2d8de00464107e5a143594068461af21ece9fb542e2f254b6f895eea6a6627f4f7c438a42fb18af7f539c4be2456661a5beec4a561f9443988182445b3952a5d9321a2d725b24b151f79a2806432c848b0b0c02576676e3a5c6f0661b4e318ca4f3e134d066808fab8fdd5322ed5cf5ad68aae43254a8fefdb69809c1bfdc07fe0365f38baa424d0c059c3a9fbff1f3525dae410740b9719929ef3f34235da519591f0410a08438132600fa802079b8d6f372f6dc439eb1b100aed28bb55cc3c6dc8982644940bd506278943fa8e430836cb874283e9f4438aac04a817f86bd1606036f03d196a211bdd91ac683d4ec63fcd503aa97b53d5c2571d39855b2be5f77be80a7f767271c8789aec26c66530c22387007c704f96b1a76a47e8e13fb263a0a6b24b2959495d34b47e03bcb95e8af13b555c5c403ec01427182afa1bae35ff81224b051fde7a61bd9044ed74042444a05e06186eedacc38c0128ff7d70c',
firstName: 'FirstName'
},
className: "logOutForDisagreement"
}
};
//You don't need the props for everything, just the className, but I'm leaving them h
describe('Test the log out for disagreement button', () => {
it('renders correctly enzyme and has onclick', async () => {
const { getByText } = render(<LogOutForDisagreement id="logOutForDisagreementClipboard" className={props.className} props={props} onChange={jest.fn()} />);
fireEvent.click(screen.getByRole('button', {
name: /log out/i
}));
//await expect(spy).toHaveBeenCalled();
expect(mockStore.clearAll).toHaveBeenCalledTimes(1);
expect(toJson(getByText)).toMatchSnapshot();
});
});
Code Coverage
--------------------------------------------|---------|----------|---------|---------|----------------------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
--------------------------------------------|---------|----------|---------|---------|----------------------------------
All files | 25.95 | 8.06 | 18.94 | 26.33 |
src/components/privacyPolicyComponents | 25 | 0 | 21.05 | 25 |
LogOutForDisagreement.js | 100 | 100 | 100 | 100 |
Does anyone know why it reports that I called the function twice now? Should I just use toHaveBeenCalled? I still get an error that it got called twice.
expect(jest.fn()).toHaveBeenCalledTimes(expected)
Expected number of calls: 1
Received number of calls: 2
I have a simple pop-up that I want to test if the clicked button closes the popup using testing-library/react. The way shown in docs doesn't work for me for some reason. I'm able to console log the button, so the query works but fireEvent doesn't trigger the button.
test("close the popup", () => {
render(
<Popup>
<div id="content"></div>
</Popup>
);
const button = screen.getByText("Got It");
fireEvent.click(button);
expect(button).not.toBeInTheDocument();
});
import React, { useEffect, useState } from "react";
import PropTypes from "prop-types";
const Popup = (props) => {
const id = "popup-active"
const [popupActive, setPopupActive] = useState(() => {
const value = window.localStorage.getItem(id);
return value !== null ? JSON.parse(value) : true;
});
useEffect(() => {
window.localStorage.setItem(id, popupActive);
}, [popupActive]);
const handleX = () => {
setPopupActive(!popupActive);
};
return (
<div
style={{
visibility: popupActive ? "visible" : "hidden",
opacity: popupActive ? "1" : "0",
}}
className={popupStyles.overlay}
>
<div className={popupStyles.popup}>
<div className={popupStyles.content}>{props.children}</div>
<button
data-testid="button-popup"
className={popupStyles.button}
onClick={handleX}
>
Got It
</button>
</div>
</div>
);
};
export default Popup;
You should use toBeVisible matcher.
This allows you to check if an element is currently visible to the user.
An element is visible if all the following conditions are met:
it is present in the document
it does not have its css property display set to none
it does not have its css property visibility set to either hidden or collapse
it does not have its css property opacity set to 0
its parent element is also visible (and so on up to the top of the DOM tree)
it does not have the hidden attribute
if <details /> it has the open attribute
E.g.
index.tsx:
import React from 'react';
import { useEffect, useState } from 'react';
const id = 'popup-active';
const Popup = (props) => {
const [popupActive, setPopupActive] = useState(() => {
const value = window.localStorage.getItem(id);
return value !== null ? JSON.parse(value) : true;
});
useEffect(() => {
window.localStorage.setItem(id, popupActive);
}, [popupActive]);
const handleX = () => {
setPopupActive(!popupActive);
};
return (
<div
style={{
visibility: popupActive ? 'visible' : 'hidden',
opacity: popupActive ? '1' : '0',
}}
>
<div>
<div>{props.children}</div>
<button data-testid="button-popup" onClick={handleX}>
Got It
</button>
</div>
</div>
);
};
export default Popup;
index.test.tsx:
import { fireEvent, render, screen } from '#testing-library/react';
import '#testing-library/jest-dom/extend-expect';
import React from 'react';
import Popup from './';
describe('73407176', () => {
test('should pass', () => {
render(
<Popup>
<div id="content"></div>
</Popup>
);
const button = screen.getByText('Got It');
fireEvent.click(button);
expect(button).not.toBeVisible();
});
});
Test result:
PASS stackoverflow/73407176/index.test.tsx (11.549 s)
73407176
✓ should pass (73 ms)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 100 | 83.33 | 100 | 100 |
index.tsx | 100 | 83.33 | 100 | 100 | 8
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 12.167 s
Also check this question: What is the difference between toBeInTheDocument() and toBeVisible()?
I am new to React and I am using adazzle's React Data Grid to create an editable grid in my React application. My code below compiles successfully but when I try to run it on http://localhost:3000, it gives me the error: "TypeError: Cannot read property 'length' of undefined". Please help as I cannot see where I use the length property in my code.
index.js
import React from "react";
import ReactDOM from "react-dom";
import ReactDataGrid from "react-data-grid";
import "./styles.css";
const columns = [
{ key: "id", name: "ID", editable: true },
{ key: "title", name: "Title", editable: true },
{ key: "complete", name: "Complete", editable: true }
];
const rows = [
{ id: 0, title: "Task 1", complete: 20 },
{ id: 1, title: "Task 2", complete: 40 },
{ id: 2, title: "Task 3", complete: 60 }
];
class Example extends React.Component {
state = { rows };
onGridRowsUpdated = ({ fromRow, toRow, updated }) => {
this.setState(state => {
const rows = state.rows.slice();
for (let i = fromRow; i <= toRow; i++) {
rows[i] = { ...rows[i], ...updated };
}
return { rows };
});
};
render() {
return (
<ReactDataGrid
//rows={rows] //uncomment this line and the grid appears successfully but cannot be edited(?)
columns={columns}
rowGetter={i => this.state.rows[i]}
rowsCount={3}
onGridRowsUpdated={this.onGridRowsUpdated}
enableCellSelect={true}
/>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<Example />, rootElement);
UPDATE
Here is the error message in detail:
TypeError: Cannot read property 'length' of undefined
(anonymous function)
C:/kilostep_material/src/hooks/useViewportRows.ts:31
28 | expandedGroupIds
29 | }: ViewportRowsArgs<R>) {
30 | const [groupedRows, rowsCount] = useMemo(() => {
> 31 | if (groupBy.length === 0 || !rowGrouper) return [undefined, rawRows.length];
32 |
33 | const groupRows = (rows: readonly R[], [groupByKey, ...remainingGroupByKeys]: readonly string[], startRowIndex: number): [GroupByDictionary<R>, number] => {
34 | let groupRowsCount = 0;
View compiled
▼ 3 stack frames were expanded.
mountMemo
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:15846
useMemo
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:16219
useMemo
C:/kilostep_material/kilostep/node_modules/react/cjs/react.development.js:1532
▲ 3 stack frames were expanded.
useViewportRows
C:/kilostep_material/src/hooks/useViewportRows.ts:30
27 | rowGrouper,
28 | expandedGroupIds
29 | }: ViewportRowsArgs<R>) {
> 30 | const [groupedRows, rowsCount] = useMemo(() => {
31 | if (groupBy.length === 0 || !rowGrouper) return [undefined, rawRows.length];
32 |
33 | const groupRows = (rows: readonly R[], [groupByKey, ...remainingGroupByKeys]: readonly string[], startRowIndex: number): [GroupByDictionary<R>, number] => {
View compiled
DataGrid
C:/kilostep_material/src/DataGrid.tsx:268
265 | rawGroupBy: rowGrouper ? rawGroupBy : undefined
266 | });
267 |
> 268 | const { rowOverscanStartIdx, rowOverscanEndIdx, rows, rowsCount, isGroupRow } = useViewportRows({
| ^ 269 | rawRows,
270 | groupBy,
271 | rowGrouper,
View compiled
▼ 17 stack frames were expanded.
renderWithHooks
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:14985
updateForwardRef
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:17044
beginWork
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:19098
HTMLUnknownElement.callCallback
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:3945
invokeGuardedCallbackDev
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:3994
invokeGuardedCallback
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:4056
beginWork$1
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:23964
performUnitOfWork
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:22776
workLoopSync
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:22707
renderRootSync
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:22670
performSyncWorkOnRoot
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:22293
scheduleUpdateOnFiber
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:21881
updateContainer
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:25482
(anonymous function)
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:26021
unbatchedUpdates
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:22431
legacyRenderSubtreeIntoContainer
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:26020
render
C:/kilostep_material/kilostep/node_modules/react-dom/cjs/react-dom.development.js:26103
▲ 17 stack frames were expanded.
Module.<anonymous>
C:/kilostep_material/kilostep/src/index.js:44
41 | }
42 |
43 | const rootElement = document.getElementById("root");
> 44 | ReactDOM.render(<Example />, rootElement);
45 |
View compiled
Module../src/index.js
http://localhost:3000/static/js/main.chunk.js:203:30
__webpack_require__
C:/kilostep_material/kilostep/webpack/bootstrap:851
848 |
849 | __webpack_require__.$Refresh$.init();
850 | try {
> 851 | modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId));
| ^ 852 | } finally {
853 | __webpack_require__.$Refresh$.cleanup(moduleId);
854 | }
View compiled
fn
C:/kilostep_material/kilostep/webpack/bootstrap:150
147 | );
148 | hotCurrentParents = [];
149 | }
> 150 | return __webpack_require__(request);
| ^ 151 | };
152 | var ObjectFactory = function ObjectFactory(name) {
153 | return {
View compiled
1
http://localhost:3000/static/js/main.chunk.js:309:18
__webpack_require__
C:/kilostep_material/kilostep/webpack/bootstrap:851
848 |
849 | __webpack_require__.$Refresh$.init();
850 | try {
> 851 | modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId));
| ^ 852 | } finally {
853 | __webpack_require__.$Refresh$.cleanup(moduleId);
854 | }
View compiled
checkDeferredModules
C:/kilostep_material/kilostep/webpack/bootstrap:45
42 | }
43 | if(fulfilled) {
44 | deferredModules.splice(i--, 1);
> 45 | result = __webpack_require__(__webpack_require__.s = deferredModule[0]);
| ^ 46 | }
47 | }
48 |
View compiled
Array.webpackJsonpCallback [as push]
C:/kilostep_material/kilostep/webpack/bootstrap:32
29 | deferredModules.push.apply(deferredModules, executeModules || []);
30 |
31 | // run deferred modules when all chunks ready
> 32 | return checkDeferredModules();
| ^ 33 | };
34 | function checkDeferredModules() {
35 | var result;
View compiled
(anonymous function)
http://localhost:3000/static/js/main.chunk.js:1:69
This screen is visible only in development. It will not appear if the app crashes in production.
Open your browser’s developer console to further inspect this error. Click the 'X' or hit ESC to dismiss this message.
I finally got the React Data Grid to run and be editable as in the example sandbox code by uninstalling the 7.0.1 version and installing the 5.0.1 version which was the one in use by the sandbox (although there are other sandboxes with earlier versions e.g. 3.0.2 which also works).
I typed the following commands:
npm uninstall react-data-grid
npm install react-data-grid#5.0.1
Or with yarn:
yarn remove react-data-grid
yarn add react-data-grid#5.0.1
Every time I try to render the page, this error is thrown. I tried multiple solutions but none of them worked.
Current react version is 17.0.2, node version is 14.16.1
Here the important code snippets:
import { useAuthUser, useFeatureFlags, useUser, useClaim, firebase } from './lib'
import React from 'react'
...
function App () {
console.log(React.version)
const [flags, flagsLoading] = useFeatureFlags() // last executed line here
...
import useCollection from './useCollection'
const useFeatureFlags = () => {
const [flagData, , loading, error] = useCollection('featureFlags') // last executed line here
...
}
export default useFeatureFlags
import { useState, useEffect } from 'react'
import { db } from '../firebase'
const useCollection = (path) => {
const [loading, setLoading] = useState(true) // here, the error is thrown
...
}
export default useCollection
I am not the author of this project, but I have to get this web app running.
Thanks for your help!
EDIT:
Here is the Stack trace and error
Error: Invalid hook call. Hooks can only be called inside of the body of a function
component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
resolveDispatcher
node_modules/react/cjs/react.development.js:1476
useState
node_modules/react/cjs/react.development.js:1507
useCollection
project/lib/build/hooks/useCollection.js:18
15 | * #returns [collectionDocuments, querySnapshot, loading, error]
16 | */
17 | const useCollection = path => {
> 18 | const [loading, setLoading] = (0, _react.useState)(true);
19 | const [ref, setRef] = (0, _react.useState)(null);
20 | const [querySnapshot, setQuerySnapshot] = (0, _react.useState)(null);
21 | const [collectionDocuments, setCollectionDocuments] = (0, _react.useState)([]);
useFeatureFlags
project/lib/build/hooks/useFeatureFlags.js:20
17 | * randomly determined rollout percentage.
18 | */
19 | const useFeatureFlags = () => {
> 20 | const [flagData,, loading, error] = (0, _useCollection.default)('featureFlags'); // const test = <useCollection path='featureFlags' />
21 | // console.log(test)
22 |
23 | const output = {};
App
src/App.js:43
40 |
41 | function App () {
42 | console.log(React.version)
> 43 | const [flags, flagsLoading] = useFeatureFlags()
44 | const [authUser, authUserLoading] = useAuthUser()
45 | const [user, userLoading] = useUser()
46 | const [claim, claimLoading] = useClaim()
./src/index.js/<
src/index.js:23
20 |
21 | console.log('project id', process.env.REACT_APP_FIREBASE_PROJECT_ID)
22 |
> 23 | ReactDOM.render(<App />, document.getElementById('root'))
24 |
./src/index.js
http://localhost:3000/static/js/main.chunk.js:24779:30
__webpack_require__
project/web/webpack/bootstrap:851
848 |
849 | __webpack_require__.$Refresh$.init();
850 | try {
> 851 | modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId));
| ^ 852 | } finally {
853 | __webpack_require__.$Refresh$.cleanup(moduleId);
854 | }
fn
project/web/webpack/bootstrap:150
147 | );
148 | hotCurrentParents = [];
149 | }
> 150 | return __webpack_require__(request);
| ^ 151 | };
152 | var ObjectFactory = function ObjectFactory(name) {
153 | return {
1
http://localhost:3000/static/js/main.chunk.js:35286:18
__webpack_require__
project/web/webpack/bootstrap:851
848 |
849 | __webpack_require__.$Refresh$.init();
850 | try {
> 851 | modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId));
| ^ 852 | } finally {
853 | __webpack_require__.$Refresh$.cleanup(moduleId);
854 | }
checkDeferredModules
project/web/webpack/bootstrap:45
42 | }
43 | if(fulfilled) {
44 | deferredModules.splice(i--, 1);
> 45 | result = __webpack_require__(__webpack_require__.s = deferredModule[0]);
| ^ 46 | }
47 | }
48 |
webpackJsonpCallback
project/web/webpack/bootstrap:32
29 | deferredModules.push.apply(deferredModules, executeModules || []);
30 |
31 | // run deferred modules when all chunks ready
> 32 | return checkDeferredModules();
| ^ 33 | };
34 | function checkDeferredModules() {
35 | var result;
(anonymous function)
http://localhost:3000/static/js/main.chunk.js:1:81
In your second and third code snippet, add
import React from "react"
Am trying to use context to allow authentication state to be available to all components. However am stumped at this error
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
src/utils/hooks.js:22
19 | // }, [pokemonName, run])
20 | const defaultInitialState = { status: "idle", data: null, error: null };
21 | function useAsync(initialState) {
> 22 | const initialStateRef = useRef({
23 | ...defaultInitialState,
24 | ...initialState
25 | });```
UseProvideAuth
src/components/helper/context.js:28
25 |
26 |
27 | function UseProvideAuth(props) {
> 28 | const {
29 | data: user,
30 | status,
31 | error,
handleSubmit
src/components/login/login-form/index.js:13
10 | function handleSubmit(event) {
11 | event.preventDefault();
12 | const { email, password } = event.target.elements;
> 13 | run(
| ^ 14 | onSubmit({
15 | email: email.value,
16 | password: password.value
Index.js
<React.StrictMode>
<ProvideAuth>
<App />
</ProvideAuth>
</React.StrictMode>,
ProvideAuth
function ProvideAuth({ children }) {
return (
<BrowserRouter>
<authContext.Provider value={UseProvideAuth}>{children}</authContext.Provider>
</BrowserRouter>
);
}
UseProvideAuth
function UseProvideAuth(props) {
const {
data: user,
status,
error,
isLoading,
isIdle,
isError,
isSuccess,
run,
setData
} = useAsync();
useAsync
const defaultInitialState = { status: "idle", data: null, error: null };
function useAsync(initialState) {
const initialStateRef = useRef({
...defaultInitialState,
...initialState
});
Here is a minimal setup on [codesandbox][1]
Any help would be appreciated.
[1]: https://codesandbox.io/s/frosty-silence-b0c8i