【发布时间】:2021-10-26 23:54:36
【问题描述】:
我制作了一个智能合约(变量rps),它会触发两个事件:
-
P1Commits(指一个新创建的游戏,返回其独特的id,以及其他内容) -
P2Joins(指以前存在的游戏,返回其独特的id,以及其他内容)
现在,我正在制作一个 React 应用程序来监听这些事件(通过这个:https://web3js.readthedocs.io/en/v1.4.0/web3-eth-contract.html#id50),并更新一个网页。
我的 React 应用应该显示两种类型的游戏:
- 打开游戏(存储在
openGames状态变量中) - 用户活跃游戏(存储在
userActiveGames状态变量中)
rps 事件应该如何影响状态:
- 当
P1Commits被触发时,一个新的游戏对象应该被添加到openGames(已经工作) - 当
P2Joins被触发时,相关游戏应该是:- 读自
openGames - 更新了
P2Joins中的信息 - 从
openGames中删除 - 添加到
userActiveGames
- 读自
但是当我尝试执行2.1(将openGames 读入tempGames)时,我得到undefined。
但是为什么呢?
我的代码:
import React, { useState, useEffect } from "react";
import web3 from "./web3";
import rps from "./rps";
const App = () => {
const [ account, setAccount ] = useState("");
const [ owner, setOwner ] = useState("");
const [ openGames, setOpenGames ] = useState({});
const [ userActiveGames, setUserActiveGames ] = useState({});
useEffect(() => {
web3.eth.getAccounts().then(accounts => setAccount(accounts[0]));
rps.methods.owner().call().then(address => setOwner(address));
rps.events.P1Commits()
.on('data', event => {
const values = event.returnValues;
const newGame = {"bet": values.bet, "over": false, "p1": values.p1, "p1Commit": values.p1Commit, "p2": null, "p2Choice": null, "p2ChoiceTime": null};
setOpenGames(prevState => ({...prevState, [values.id]: newGame}));
})
rps.events.P2Joins({
filter: {
id: Object.keys(openGames).filter(key => openGames[key].p1 === account), // ids of open games with user as player 1
p2: account // player 2 joining is user
}})
.on('data', event => {
const values = event.returnValues;
const tempGames = JSON.parse(JSON.stringify(openGames)); // copy without reference
const joinedGame = tempGames[values.id]; // why is joinedGame undefined?
[joinedGame.p2, joinedGame.p2Choice, joinedGame.p2ChoiceTime] = [values.p2, values.p2Choice, values.p2ChoiceTime];
//setOpenGames(prevState => ({...prevState, [values.id]: newGame})); // need to change this to remove games from open games
setUserActiveGames(prevState => ({...prevState, [values.id]: joinedGame}));
})
}, [])
return (
<div>
<div>
<p>Contract Owner: {owner}</p>
<p>User Account: {account}</p>
<div>
<h3>{Object.keys(openGames).length} Open Games:</h3>
<ul>
{Object.entries(openGames).map(([k, v], i) => <li key={k}>{JSON.stringify(k)}: {JSON.stringify(v)}</li>)}
</ul>
</div>
<div>
<h3>{Object.keys(userActiveGames).length} User Active Games:</h3>
<ul>
{Object.entries(userActiveGames).map(([k, v], i) => <li key={k}>{JSON.stringify(k)}: {JSON.stringify(v)}</li>)}
</ul>
</div>
</div>
</div>
);
}
export default App;
【问题讨论】:
标签: javascript reactjs react-hooks use-effect use-state