Home > database >  Cannot access 'STATE' before initialization, even though the app is rendered within a cont
Cannot access 'STATE' before initialization, even though the app is rendered within a cont

Time:10-28

I'm working on overhauling the state manage of an application I'm working on, and attempting to set it up with a context provider. I only have limited number of states to track, and it's a relatively small application so context seemed appropriate, and was a recommended solution. I've read the docs on react, but some of it isn't super clear since it's written using class components. I did some reading on stackoverflow as well for similiar implementations, but the code was not consitent between answers so I've just hacked together my best version of making sense of the tool.

I think I've maybe goofed something relatively obvious but I'm not sure what yet. Any insight appreciated. My intuition is that I've just architected something incorrectly, but I'm not sure what.

The current application currently consoles:

Cannot access 'cards' before initialization
    at App (App.jsx:30:1)

Here is App.jsx:

import { useState, useEffect, useContext } from "react";
import "./styles/App.css";
import FileHandler from "./Components/fileHandler";
import ImagePreviewer from "./Components/ImagePreviewer";
import { Header } from "./Components/Header";
import { Comparison } from "./Components/Comparison";
import { Table } from "./Components/Table";
import { backgroundQuery } from "./Components/backgroundQuery"
import { Footer } from "./Components/Footer";
import { DBContainer } from "./Components/DatabaseFunctions/DBContainer";
import { CardsContext } from "./Components/AppContext"

function App({user}) {
  const context = useContext(CardsContext);
  
  const [cards, setCards] = context[cards]
  const [previewCard, setPreviewCard] = context[previewCard]
  const [comparisonCards, setComparisonCards] = context[comparisonCards]
  const [userDBCards, setUserDBCards] = context[userDBCards];
  const [cardInput, setCardInput] = context[cardInput]

  const [background, setBackground] = useState([]);

  useEffect(() => {
    backgroundQuery()
      .then(data => {
          setBackground(data.image_uris.art_crop);
      })
      .catch(error =>
        console.log(error.message));
  }, [setBackground]);

   //insert user token into database
  return (
    <div id="master-div" className=".container"  style={{
      backgroundImage: `url(${background})`,
    }}>
        <Header
          background={background}
          setBackground={setBackground}
          cards={cards}
          user={user}
        />
        <FileHandler
          cardInput={cardInput}
          setCardInput={setCardInput}
          previewCard={previewCard}
          setPreviewCard={setPreviewCard}
          cards={cards}
          setCards={setCards}
          setComparisonCards={setComparisonCards}
          user={user}
        />
        <div className="main-container">
          <Comparison
            user={user}
            userDBCards={userDBCards}
            cards={cards}
            setCards={setCards}
            comparisonCards={comparisonCards}
            setComparisonCards={setComparisonCards}
          />
        </div>

        <div className="row .container">
          <div className="col-3 .container" id="preview-container">
            <ImagePreviewer previewCard={previewCard} cards={cards} />

          </div>
          <div className="col-6 .container" id="tableContainer">
           
            <DBContainer
              user={user}
              cards={cards}
              setCards={setCards}
              userDBCards={userDBCards}
              setUserDBCards={setUserDBCards}
              setComparisonCards={setComparisonCards}
              />
            <Table
              setComparisonCards={setComparisonCards}
              setPreviewCard={setPreviewCard}
              cards={cards}
              setCards={setCards} />
          </div>
        </div>
        <Footer />
    </div>
  );
}
export default App;

Below I have the code for my AppContext component which houses all of my context.

import { createContext, useState } from "react";

export const CardsContext = createContext();
export const BackgroundContext = createContext();

const AppContextProvider = ({children}) => {
    const [cardInput, setCardInput] = useState([]);
    const [cards, setCards] = useState([]);
    const [previewCard, setPreviewCard] = useState([]);
    const [comparisonCards, setComparisonCards] = useState([]);
    const [userDBCards, setUserDBCards] = useState([]);
    
    const [background, setBackground] = useState([]);

    return(
        <CardsContext.Provider value={{
            cards: [cards, setCards], 
            cardInput: [cardInput, setCardInput],
            previewCard: [previewCard, setPreviewCard],
            comparisonCards: [comparisonCards, setComparisonCards],
            userDBCards: [userDBCards, setUserDBCards]
            }}>
                <BackgroundContext.Provider value={[background, setBackground]}>
                    {children}
                </BackgroundContext.Provider>
        </CardsContext.Provider>
    )
}

export default AppContextProvider

This is wrapped around all of my routes in my index here:

ReactDOM.render(
  <BrowserRouter>
    <Auth0ProviderWithRedirectCallback
      domain={process.env.REACT_APP_DOMAIN}
      clientId={process.env.REACT_APP_CLIENT_ID}
      redirectUri={window.location.origin}
    >
      <AppContextProvider>
        <Routes>
          <Route path="/"              element={<ProtectedRoute component={App}/>} />
          <Route path="/profile/:id"   element={<ProtectedRoute component={ProfilePage}/>} />
          <Route path='/auth'          element={<Auth />} />
          {/* The below route should fire for upload list, rendering a page of thier cards. */}
          <Route path='/profile/:id/:list' element={<ListPage />} />
        </Routes>
      </AppContextProvider>
    </Auth0ProviderWithRedirectCallback>
  </BrowserRouter>,
  document.getElementById('root')
);

CodePudding user response:

You should wrap your context[cards] in quotes like so context["cards"]. Now the app tries to get the context with the value of cards which is not defined yet.

Same for the other context[...]

  • Related