2

I'm trying to make ContextAPI work on my application, webpack compiles everything, but on the browser I get

Uncaught TypeError: react__WEBPACK_IMPORTED_MODULE_0__.useContext(...) is not iterable

This is the first I'm trying to use ContextAPI in a project.

On index.js

 ReactDOM.render(
    <React.StrictMode>
        <Router>
            <RoutesTree />
        </Router>
    </React.StrictMode>,
    document.getElementById('app')
);

on RoutesTree.js

const DEFAULT_STATE = {
    state: {
        users: [],
        teams: []
    },
    setState: () => {}
};

export const AppContext = createContext(DEFAULT_STATE);

const RoutesTree = () => {
    const [state, setState] = useState(DEFAULT_STATE.state);
    const value = useMemo(
      () => ((state, setState)),
      [state]
    );
  
    console.log('state', state);

    return (
        <AppContext.Provider value={value}>
            <Routes>
                <Route path='/' element={<App />} />
                <Route path='/teams/:id' element={<Team />} />
            </Routes>
        </AppContext.Provider>
    )
}

export default RoutesTree;

on App.js (work in progress)

const App = () => {

  return (
      <>
          <Home />
      </>
  );
}

on Home.js

const Home = () => {
    const [state, setState] = useContext(AppContext);

    useEffect(() => {
        const getTeams = async () => {
            const response = await axios.get(teamsApiUrl);
            
            setState((prevState) => ({
                teams: response.data,
                users: prevState.users
            }));
        }

        getTeams();
    }, [])

Complete error:

Uncaught TypeError: react__WEBPACK_IMPORTED_MODULE_0__.useContext(...) is not iterable
    Home webpack://ecore-project/./src/components/Home/Home.js?:32
    React 16
    <anonymous> webpack://ecore-project/./src/index.js?:15
    js http://localhost:8080/main.js:500
    __webpack_require__ http://localhost:8080/main.js:1313
    <anonymous> http://localhost:8080/main.js:2403
    <anonymous> http://localhost:8080/main.js:2405 main.js line 434 > eval:32:78 The above error occurred in the <Home> component:

Home@webpack://ecore-project/./src/components/Home/Home.js?:32:78 App Routes@webpack://ecore-project/./node_modules/react-router/index.js?:922:7 RoutesTree@webpack://ecore-project/./src/components/RoutesTree/RoutesTree.js?:25:76 Router@webpack://ecore-project/./node_modules/react-router/index.js?:860:7 BrowserRouter@webpack://ecore-project/./node_modules/react-router-dom/index.js?:122:7

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. react-dom.development.js:18572:15
    React 16
    <anonymous> webpack://ecore-project/./src/index.js?:15
    js http://localhost:8080/main.js:500
    __webpack_require__ http://localhost:8080/main.js:1313
    <anonymous> http://localhost:8080/main.js:2403
    <anonymous> http://localhost:8080/main.js:2405 Uncaught TypeError: react__WEBPACK_IMPORTED_MODULE_0__.useContext(...) is not iterable
    Home webpack://ecore-project/./src/components/Home/Home.js?:32
    React 13
    <anonymous> webpack://ecore-project/./src/index.js?:15
    js http://localhost:8080/main.js:500
    __webpack_require__ http://localhost:8080/main.js:1313
    <anonymous> http://localhost:8080/main.js:2403
    <anonymous> http://localhost:8080/main.js:2405

webpack compiler:

<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: http://localhost:8080/
<i> [webpack-dev-server] On Your Network (IPv4): http://192.168.0.100:8080/
<i> [webpack-dev-server] Content not from webpack is served from 'C:\Users\Alvaro\git\ecore-project\public' directory
asset main.js 1.84 MiB [emitted] (name: main)
asset ./index.html 230 bytes [emitted]
runtime modules 27.5 KiB 14 modules
modules by path ./node_modules/ 1.61 MiB 90 modules
asset modules 4.4 KiB
  data:image/svg+xml,%3csvg xmlns=%27.. 281 bytes [built] [code generated]
  data:image/svg+xml,%3csvg xmlns=%27.. 279 bytes [built] [code generated]
  data:image/svg+xml,%3csvg xmlns=%27.. 161 bytes [built] [code generated]
  data:image/svg+xml,%3csvg xmlns=%27.. 271 bytes [built] [code generated]
  + 12 modules
modules by path ./src/ 12.8 KiB
  modules by path ./src/components/ 7.9 KiB 6 modules
  modules by path ./src/*.js 683 bytes 2 modules
  modules by path ./src/*.css 2.66 KiB 2 modules
  ./src/utils/usePagination.js 1.59 KiB [built] [code generated]
webpack 5.72.1 compiled successfully in 1741 ms

1 Answer 1

2

Issue

The issue is how you are trying to compute a memoized context value.

const value = useMemo(
  () => ((state, setState)), // <-- not an iterable value!
  [state]
);

It's not exactly what you think it is, and the code blows up in the Home component when it tries to use array destructuring assignment to access the state and state updater function.

const [state, setState] = useContext(AppContext); // <-- tries to access array

() => ((state, setState)) is actually returning the result of a Comma Operator expression. The setState function is what is returned as a memoized value.

Compounding this issue is that the context value was declared to be an object and not an array.

const DEFAULT_STATE = {
  state: {
    users: [],
    teams: []
  },
  setState: () => {}
};

export const AppContext = createContext(DEFAULT_STATE);

Solution

I am certain you meant to memoize an object instead.

const value = useMemo(
  () => ({ state, setState }),
  [state]
);

Now the consumer needs to destructure the object correctly. It's an object, not an array.

const { state, setState } = useContext(AppContext);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.