ошибка во время дождливого useCacheCall(): TypeError: не удается прочитать свойство ‘methods’ из undefined

#javascript #react-hooks #drizzle

#javascript #реагирующие хуки #морось

Вопрос:

Я пытаюсь вызвать перехват drizzle useCacheCall() компонента React из двух разных мест. Это вызванный компонент React

 const FamilyContainer = ({ member }) => {
  console.log("inside family container, member: ", member);
  const { useCacheCall } = drizzleReactHooks.useDrizzle();
  const organization = useCacheCall("MyContract", "getOrganization", member);
  console.log("organization: ", organization amp;amp; organization);

  const maxLevel = useCacheCall("MyContract", "levels");
  console.log("maxLevel: ", maxLevel amp;amp; typeof maxLevel);

  if (!isLoaded(organization) || !isLoaded(maxLevel)) {
    return "loading...";
  }
  if (isEmpty(organization) || isEmpty(maxLevel)) return <PageNotFound />;

  return (
    <FamilySection
      organization={organization}
      maxLevel={parseInt(maxLevel, 10)}
    />
  );
};

export default FamilyContainer;
  

Я вызываю вышеупомянутый компонент React из первого местоположения, скопировав вставив URL-адрес в адресную строку браузера:http://localhost:3000/#/invited/7434DC1BF0, которое успешно выполняется. это код вызова:

 const InviteReceived = ({ playerAccount, inviterData }) => {
  const useStyles = makeStyles((theme) => ({
    root: {
      flexGrow: 1,
    },
  }));
  const classes = useStyles();
  const history = useHistory();

  return (
    <Grid container spacing={0}>
      <Grid item xs={12} sm={12} md={12} lg={5}>
        <Box
          display="flex"
          flexDirection="column"
          justifyContent="center"
          p={1}
          m={0}
          bgcolor="black"
        >
          <InviteReceivedSection
            playerAccount={playerAccount}
            inviterAccount={inviterData.ID}
          />
          <PayTributeSection playerAccount={playerAccount} />
        </Box>
      </Grid>
      <Grid item xs={12} sm={12} md={12} lg={7}>
        <FamilyContainer member={inviterData.ID} />
      </Grid>
    </Grid>
  );
};

export default InviteReceived;
  

Вызов из второго местоположения точно такого же компонента React путем копирования, вставки URL-адреса в адресную строку браузера:http://localhost:3000/#/member/0x16Aa59291f0C27586B87CDcF48630cB721Dcd0cC , продолжает повторяться сбой с сообщением об ошибке: ошибка типа: не удается прочитать свойство ‘methods’ из неопределенного. Но если я сначала выполняю первый вызов, а затем вызываю второй компонент (используя URL-адреса), то ошибки не происходит (странно).

 const MemberComponent = ({ playerAccount }) => {
  console.log("Inside member component, playeraccount ", playerAccount);

  const useStyles = makeStyles((theme) => ({
    root: {
      flexGrow: 1,
    },
  }));
  const classes = useStyles();
  const history = useHistory();

  return (
    <Grid container spacing={0}>
      <Grid item xs={12} sm={12} md={12} lg={5}>
        <Box
          display="flex"
          flexDirection="column"
          justifyContent="center"
          p={1}
          m={0}
          bgcolor="black"
        >
          <ProfileDetailsSection playerAccount={playerAccount} />
          <RecruitSection playerAccount={playerAccount} />
        </Box>
      </Grid>
      <Grid item xs={12} sm={12} md={12} lg={7}>
        <FamilyContainer member={playerAccount} />
      </Grid>
    </Grid>
  );
};

export default MemberComponent;
  

Это трассировка ошибки:

  TypeError: Cannot read property 'methods' of undefined
    current
    C:/src/hooks/create-use-cache-call.js:19
      16 |     {}
      17 |   )
      18 | } else {
    > 19 |   const instance = drizzle.contracts[contractNameOrNames]
         | ^  20 |   const cacheKey = instance.methods[methodNameOrFunction].cacheCall(...args)
      21 |   const cache =
      22 |     drizzleState.contracts[contractNameOrNames][methodNameOrFunction][
    View compiled
    e.useDrizzleState
    C:/src/hooks/index.js:36
      33 | 
      34 | // This is the escape hatch mentioned above. We keep a ref to `args` and whenever they change, we immediately update the state just like in the subscription.
      35 | // This won't have any effect if `args` is undefined.
    > 36 | const argsRef = useRef(args)
         | ^  37 | const [state, setState] = useState(
      38 |   mapStateRef.current(drizzle.store.getState())
      39 | )
    View compiled
    (anonymous function)
    C:/src/hooks/create-use-cache-call.js:8
       5 |   methodNameOrFunction,
       6 |   ...args
       7 | ) => {
    >  8 |   const isFunction = typeof methodNameOrFunction === 'function'
       9 |   const drizzleState = useDrizzleState(drizzleState => {
      10 |     if (isFunction) {
      11 |       return contractNameOrNames.reduce(
    View compiled
    FamilyContainer
    C:/code/MyContract/codebase/client/src/containers/FamilyContainer.js:10
       7 | const FamilyContainer = ({ member }) => {
       8 |   console.log("inside family container, member: ", member);
       9 |   const { useCacheCall } = drizzleReactHooks.useDrizzle();
    > 10 |   const organization = useCacheCall("MyContract", "getOrganization", member);
      11 |   console.log("organization: ", organization amp;amp; organization);
      12 | 
      13 |   const maxLevel = useCacheCall("MyContract", "levels");
    View compiled
    ▶ 16 stack frames were collapsed.
    Module../src/index.js
    C:/code/MyContract/codebase/client/src/index.js:100
       97 | const drizzle = new Drizzle(drizzleOptions, reduxStore);
       98 | console.log("Drizzle: ", drizzle, " reduxStore: ", reduxStore);
       99 | 
    > 100 | ReactDOM.render(
      101 |   <React.StrictMode>
      102 |     <ThemeProvider theme={theme}>
      103 |       <drizzleReactHooks.DrizzleProvider drizzle={drizzle}>
    View compiled
    __webpack_require__
    C:/code/MyContract/codebase/client/webpack/bootstrap:784
      781 | };
      782 | 
      783 | // Execute the module function
    > 784 | modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId));
          | ^  785 | 
      786 | // Flag the module as loaded
      787 | module.l = true;
    View compiled
    fn
    C:/code/MyContract/codebase/client/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:7398:18
    __webpack_require__
    C:/code/MyContract/codebase/client/webpack/bootstrap:784
      781 | };
      782 | 
      783 | // Execute the module function
    > 784 | modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId));
          | ^  785 | 
      786 | // Flag the module as loaded
      787 | module.l = true;
    View compiled
    checkDeferredModules
    C:/code/MyContract/codebase/client/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]
    http://localhost:3000/static/js/bundle.js:33:19
      30 | /******/     deferredModules.push.apply(deferredModules, executeModules || []);
      31 | /******/
      32 | /******/     // run deferred modules when all chunks ready
    > 33 | /******/     return checkDeferredModules();
         |                   ^  34 | /******/   };
      35 | /******/   function checkDeferredModules() {
      36 | /******/     var resu<
    View source
  

ОБНОВЛЕНИЕ: кроме того, я обнаружил, что проблема возникает только тогда, когда я размещаю ссылку непосредственно в адресной строке. но если компонент перемещается внутри из какого-либо другого компонента, то ошибка не возникает. есть идеи относительно того, почему? Есть идеи, что может вызывать проблему только при одном вызове?

Комментарии:

1. кроме того, мой маршрутизатор: <Switch> <Route exact path="/" render={() => <HomePageContainer />} /> <Route path="/invited/:inviteCode" render={({ match }) => ( <InviteReceivedContainer inviteCode={match.params.inviteCode} /> )}/> <Route path="/member/:memberAddress" render={({ match }) => ( <MemberContainer playerAccount={match.params.memberAddress} /> )}/> <Route render={() => <PageNotFound />} /> </Switch>

Ответ №1:

наконец-то найдена проблема. поскольку я использовал URL напрямую, второй вызов (тот, который выдает ошибку) выполнял useCacheCall() еще до того, как морось должным образом инициализировалась и установила соединение с ethereum. Ввод </drizzleReactHooks.Инициализатор> компонент в моем < App /> решил проблему:

 <drizzleReactHooks.Initializer
      error="There was an error."
      loadingContractsAndAccounts="loading contracts amp; accounts..."
      loadingWeb3="loading web3..."
    >
<App/>
</drizzleReactHooks.Initializer>