#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>