I am using this to store state in a React app(hooks based) instead of redux.
import React, { createContext, useContext, useReducer } from "react";
//Prepares the datalayer
export const StateContext = createContext()
//Wrap our app and provide the data layer
export const StateProvider = ({ reducer, initialState, children }) => (
<StateContext.Provider value={useReducer(reducer, initialState)}>
{children}
</StateContext.Provider>
)
//Pull information from the data layer
export const useStateValue = () => useContext(StateContext)
//Accepts a context object (the value returned from React.createContext) and returns the current context value, as given by the nearest context provider for the given context.
I am using above as:
import React,{useState} from 'react'
import { useHistory } from 'react-router-dom';
import { useStateValue } from '../../store/StateProvider';
function Header() {
const [{ basket, user }, dispatch] = useStateValue();
const logout = () => {
dispatch({
type:'DELETE_USER'
})
history.replace('/')
}
return (
<>
<button className="btn-logout" onClick={ logout } tabIndex="0">
{ user ? ('Logout') : '' }
</button>
</>
)
}
export default Header
When I run 'npm test'
This error is shown:
TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))
5 | function Header() {
6 | let history = useHistory();
> 7 | const [{ basket, user }, dispatch] = useStateValue();
| ^
8 |
9 | const logout = () => {
10 | dispatch({
at Header (src/components/header/Header.js:7:42)
at renderWithHooks (node_modules/react-dom/cjs/react-dom.development.js:14985:18)
at mountIndeterminateComponent (node_modules/react-dom/cjs/react-dom.development.js:17811:13)
at beginWork (node_modules/react-dom/cjs/react-dom.development.js:19049:16)
at HTMLUnknownElement.callCallback (node_modules/react-dom/cjs/react-dom.development.js:3945:14)
at HTMLUnknownElement.callTheUserObjectsOperation (node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30)
at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:318:25)
at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:274:3)
at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:221:9)
at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:94:17)
at HTMLUnknownElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:231:34)
at Object.invokeGuardedCallbackDev (node_modules/react-dom/cjs/react-dom.development.js:3994:16)
at invokeGuardedCallback (node_modules/react-dom/cjs/react-dom.development.js:4056:31)
at beginWork$1 (node_modules/react-dom/cjs/react-dom.development.js:23964:7)
at performUnitOfWork (node_modules/react-dom/cjs/react-dom.development.js:22779:12)
at workLoopSync (node_modules/react-dom/cjs/react-dom.development.js:22707:5)
at renderRootSync (node_modules/react-dom/cjs/react-dom.development.js:22670:7)
at performSyncWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:22293:18)
at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom.development.js:21881:7)
at updateContainer (node_modules/react-dom/cjs/react-dom.development.js:25482:3)
at node_modules/react-dom/cjs/react-dom.development.js:26021:7
at unbatchedUpdates (node_modules/react-dom/cjs/react-dom.development.js:22431:12)
at legacyRenderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:26020:5)
at Object.render (node_modules/react-dom/cjs/react-dom.development.js:26103:10)
at node_modules/@testing-library/react/dist/pure.js:99:25
at batchedUpdates$1 (node_modules/react-dom/cjs/react-dom.development.js:22380:12)
at act (node_modules/react-dom/cjs/react-dom-test-utils.development.js:1042:14)
at render (node_modules/@testing-library/react/dist/pure.js:95:26)
at Object.<anonymous> (src/components/header/Header.test.js:30:5)
console.error Error: Uncaught [TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))] at reportException (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jsdom\lib\jsdom\living\helpers\runtime-script-errors.js:62:24) at innerInvokeEventListeners (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:333:9) at invokeEventListeners (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:274:3) at HTMLUnknownElementImpl._dispatch (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:221:9) at HTMLUnknownElementImpl.dispatchEvent (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:94:17) at HTMLUnknownElement.dispatchEvent (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jsdom\lib\jsdom\living\generated\EventTarget.js:231:34) at Object.invokeGuardedCallbackDev (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:3994:16) at invokeGuardedCallback (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:4056:31) at beginWork$1 (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:23964:7) at performUnitOfWork (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:22779:12) TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator)) at Header (C:\Users\Shubh\Desktop\react-star-wars\src\components\header\Header.js:7:42) at renderWithHooks (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:14985:18) at mountIndeterminateComponent (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:17811:13) at beginWork (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:19049:16) at HTMLUnknownElement.callCallback (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:3945:14) at HTMLUnknownElement.callTheUserObjectsOperation (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jsdom\lib\jsdom\living\generated\EventListener.js:26:30) at innerInvokeEventListeners (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:318:25) at invokeEventListeners (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:274:3) at HTMLUnknownElementImpl._dispatch (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:221:9) at HTMLUnknownElementImpl.dispatchEvent (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:94:17) at HTMLUnknownElement.dispatchEvent (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jsdom\lib\jsdom\living\generated\EventTarget.js:231:34) at Object.invokeGuardedCallbackDev (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:3994:16) at invokeGuardedCallback (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:4056:31) at beginWork$1 (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:23964:7) at performUnitOfWork (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:22779:12) at workLoopSync (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:22707:5) at renderRootSync (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:22670:7) at performSyncWorkOnRoot (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:22293:18) at scheduleUpdateOnFiber (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:21881:7) at updateContainer (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:25482:3) at C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:26021:7 at unbatchedUpdates (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:22431:12) at legacyRenderSubtreeIntoContainer (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:26020:5) at Object.render (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:26103:10) at C:\Users\Shubh\Desktop\react-star-wars\node_modules@testing-library\react\dist\pure.js:99:25 at batchedUpdates$1 (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom.development.js:22380:12) at act (C:\Users\Shubh\Desktop\react-star-wars\node_modules\react-dom\cjs\react-dom-test-utils.development.js:1042:14) at render (C:\Users\Shubh\Desktop\react-star-wars\node_modules@testing-library\react\dist\pure.js:95:26) at Object. (C:\Users\Shubh\Desktop\react-star-wars\src\components\header\Header.test.js:30:5) at Promise.then.completed (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jest-circus\build\utils.js:276:28) at new Promise () at callAsyncCircusFn (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jest-circus\build\utils.js:216:10) at _callCircusTest (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jest-circus\build\run.js:212:40) at processTicksAndRejections (internal/process/task_queues.js:97:5) at _runTest (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jest-circus\build\run.js:149:3) at _runTestsForDescribeBlock (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jest-circus\build\run.js:63:9) at _runTestsForDescribeBlock (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jest-circus\build\run.js:57:9) at run (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jest-circus\build\run.js:25:3) at runAndTransformResultsToJestFormat (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jest-circus\build\legacy-code-todo-rewrite\jestAdapterInit.js:176:21) at jestAdapter (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jest-circus\build\legacy-code-todo-rewrite\jestAdapter.js:109:19) at runTestInternal (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jest-runner\build\runTest.js:380:16) at runTest (C:\Users\Shubh\Desktop\react-star-wars\node_modules\jest-runner\build\runTest.js:472:34)
at VirtualConsole.<anonymous> (node_modules/jsdom/lib/jsdom/virtual-console.js:29:45)
at reportException (node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:66:28)
at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:333:9)
at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:274:3)
at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:221:9)
at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:94:17)
console.error The above error occurred in the component:
at Header (C:\Users\Shubh\Desktop\react-star-wars\src\components\header\Header.js:6:19)
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
at logCapturedError (node_modules/react-dom/cjs/react-dom.development.js:20085:23)
at update.callback (node_modules/react-dom/cjs/react-dom.development.js:20118:5)
at callCallback (node_modules/react-dom/cjs/react-dom.development.js:12318:12)
at commitUpdateQueue (node_modules/react-dom/cjs/react-dom.development.js:12339:9)
at commitLifeCycles (node_modules/react-dom/cjs/react-dom.development.js:20736:11)
at commitLayoutEffects (node_modules/react-dom/cjs/react-dom.development.js:23426:7)
at HTMLUnknownElement.callCallback (node_modules/react-dom/cjs/react-dom.development.js:3945:14)
Test Suites: 1 failed, 1 total Tests: 1 failed, 1 total
useReducer
hook in as your context value like that... call it before returning your provider, and then pass in what you want the state value to be. It might also be better to define some specific values and functions you want to pass down to the rest of the app, rather than just handing everything fromuseReducer
down. If you just pass everything down you're bleeding an implementation detail about how your state context works, which the rest of the app shouldn't really know about. For example I'd put your logout function in the provider and pass it down – James