宇宙链 宇宙链
Ctrl+D收藏宇宙链

昨天的区块链「百度贴吧」还差一个用户界面 代码都在这儿

作者:

时间:1900/1/1 0:00:00

本文目的很明确:手把手教你使用DApp开发框架Embark构建一个去中心化百度贴吧,主要包括以下3部分:

明确DApp需求,部署智能合约;

使用EmbarkJS测试智能合约;

使用React构建DApp的前端。

在上一篇文章中,营长手把手带你们使用Solidity语言部署合约,并使用EmbarkJS完成智能合约测试,本文基于此将继续深入,使用JavaScript用户界面框架React构建去中心化百度贴吧的前端。

渲染第一个组件

在构建与智能合约实例交互的组件之前,我们需要先在屏幕上实际渲染一个简单的文本,以确保React框架已经得到了正确的配置。

为此,我们需要将React框架添加为项目的依赖项。事实上,我们的代码依赖两个程序包:react和react-dom。之所以需要react-dom是因为它可以在DOM(DocumentObjectModel,文档对象模型)环境中渲染使用React框架定义的组件,听起来令人摸不着头脑,简单来说这就是浏览器所做的工作。

接下来我们需要将这两个依赖项添加到项目的package

...}

接下来,我们将该状态绑定到表单字段:

TopicPost你可能会问代码中的loading是干嘛的,别着急,我们马上会说到它。最后但同样重要的是,我们需要添加一些事件处理程序,以便在用户输入数据时视图中的更改能传递回组件并更新组件的状态。为了确保一切正常,我们还需要为表单提交添加一个事件处理程序,让它输出状态对象state中的数据,换句话说,我们需要更新处理程序handleChange()和创建帖子处理程序createPost(),代码如下:

exportclassCreatePostextendsComponent{..

createPost(event){event

...}

请注意代码中更新处理程序handleChange()的实现方式,我们在其中使用了设置状态函数setState()来更新传递给该函数的值。现在我们需要做的就是将这些处理程序附加到表单中:

createPost(e。>TopichandleChange('topic',e。/>handleChange('content',e})>Post由于我们正在使用表单的onSubmit()处理程序,因此很重要的一点就是将type=“submit”添加到按钮对象button中,或将按钮对象更改为,否则,表单将不会发出提交事件。

做完了这些,在提交表单时我们就能在控制台中看到组件的状态了!接下来最大的挑战就是使用EmbarkJS和它的API实现组件与智能合约实例的交互。

1、将数据上传到IPFS

回想一下我们刚才的定义,DReddit中创建帖子函数createPost()接收一些字节作为帖子的描述,我们也讨论了,这些字节实际上并不是帖子自身的数据,而是能够指向帖子数据的IPFS哈希值。换句话说,我们必须以某种方式将数据上传到IPFS中,并获得这样的哈希值。

幸运的是,强大的EmbarkJS为我们提供了大量的API来实现这个功能!就比如说,EmbarkJS的存储文档函数EmbarkJS

美国共和党谈判代表:昨天债务谈判出现重大挫折:金色财经报道,美国众议院议长麦卡锡表示,他将在周一下午会见拜登。债务上限谈判代表周日将会面。美国共和党谈判代表称,昨天债务谈判出现重大挫折,任何债务协议都需要有多年支出上限。[2023/5/22 15:17:25]

代码中我们使用了将JavaScript对象转换为字符串的函数JSON

asynccomponentDidMount(){constipfsHash=web3

...}

这里需要强调的一点是:在页面加载时调用数据获取函数EmbarkJS

);

这也意味着我们的应用程序只会在EmbarkJS准备就绪时执行渲染,展示数据。从理论上来说,这样做等待的时间可能会变长,但就我们这个DReddit应用程序而言,造成影响的可能性不大。

我们还需要添加帖子所有者和帖子创建日期。按照预期,所有者和创建日期都将作为帖子的属性被记录下来。我们只需要以用户可以理解的方式对数据进行格式化,展示所有者并不会有什么问题,但要以人类可读的形式展示日期就需要安装并导入日期格式库dateformat,安装的操作如下所示:

npminstall--savedateformat

安装完成后,我们需要更新帖子组件Post的渲染函数render(),将得到的帖子创建日期creationDate转换成人类可读的形式。

..

当我们添加帖子时,帖子个数posts

render(){return({this

list=awaitPromise

...}

请注意,在上面的代码中,我们并没有用await语句来等待每次对帖子的调用。这是故意为之,因为我们不可能等待每一个承诺的完成,所以我们会收集所有需要的承诺,然后使用Promise

);this

到现在为止,我们的DReddit应用程序已经可以展示所有已创建帖子的列表。但遗憾的是,在添加新帖子时,它并不会自动重新加载帖子。因此,我们必须在每次添加帖子后刷新浏览器,这样做十分影响用户体验,我们现在需要解决这个问题。

b)重新加载帖子

我们有多种不同的方法来实现帖子列表的重新加载,最简单的一种就是让创建帖子组件createPost告诉帖子列表组件List重新加载帖子。但是,我们构建的这个React应用程序并没有设置通信层,所以最直接的方法就是更改创建帖子组件CreatePost和帖子列表组件List的父组件(在这里就是App组件)中加载帖子的逻辑,让这个父组件把逻辑传递到需要它的地方。这也意味着我们将把获取帖子列表的功能放在App组件中,帖子列表组件List仅仅接收传递过来的纯数据。

这个实现方法听起来很绕,但不用担心,在代码中实现它并不难!我们首先需要在App组件中定义一个读取帖子函数loadPosts(),然后基本上我们需要把帖子列表组件List中componentDidMount()函数的所有功能都移动到App组件中:

exportclassAppextendsComponent{..

}list=awaitPromise

);list;this

}

为了完成这项工作,我们还需要引入一个帖子的状态,这样就可以确保App组件在挂载时会调用读取帖子函数loadPosts():

exportclassAppextendsComponent{constructor(props){super(props);this

asynccomponentDidMount(){awaitthis

...}

最后但同样重要的是,我们需要将帖子传递给帖子列表组件List并将加载帖子函数loadPosts()传递给创建帖子组件CreatePost作为回调处理程序:

render(){return(DReddit

完成后,我们可以分别从this

有了这些功能。在新创建帖子时,帖子列表会自动重新加载,你大可去试一试。

添加投票功能

我们将要实现的最后一个功能就是对帖子进行好评还是差评的投票。这需要我们回到刚刚创建的帖子组件Post中进行更改,首先我们必须明确此处更改要实现的功能:

展示每个帖子的好评数和差评数;

为用户分别添加处理好评投票和差评投票的处理程序;

确定用户是否可以对帖子进行投票。

a)渲染帖子的票数

第一个功能是其中最琐碎的一个,所以我们先来进行它的攻关。虽然DReddit智能合约返回的数据中已经附加了好评数和差评数,但它的格式并不正确,因为智能合约返回的数据是字符串形式。接下来我们需要扩展App组件的加载帖子函数loadPosts()来实现对帖子好评数和差评数的解析,代码如下:

asyncloadPosts(){..

);...}

完成后,我们可以通过帖子列表组件List中的props对象将每个帖子的好评数和差评数传递给每个帖子组件Post:

exportclassListextendsComponent{..

我们还希望在成功发送投票后更新视图。我们需要通过帖子的props对象获取帖子的好评差评投票并相应地渲染它们。但是,如果在接收到投票后立刻更新这些值就好了。为此,我们需要更改代码,让它只读取一次来自props对象的好评差评投票并将它们存储在组件的状态中。

exportclassPostextendsComponent{constructor(props){super(props);this

...}

同时我们还需要更改组件的渲染函数render(),让它从组件状态中读取数据而不是从props对象中:

render(){..

大功告成,我们现在可以对帖子进行好评差评投票,且对每个帖子只能投票一次,没错,当我们对一个帖子多次投票时,程序会报错。这是因为,我们在智能合约中加入了一项限制条件,确保用户无法对已经投票或还未创建的帖子进行好评差评投票。

成功近在眼前,最后我们只需要将这个投票限制逻辑加入前端程序中。

c)使用函数canVote()禁用投票按钮

这个投票限制逻辑实现起来非常简单。如果用户不能对帖子投票,我们只需要禁用投票按钮。我们可以通过调用智能合约中能否投票函数canVote()来确定用户能否进行投票。同时,我们还需要考虑到,如果用户已经对一个帖子进行了投票,只是这笔包含投票的交易还未被加入到区块链中,也就是说此时投票尚未完成,这时我们不应该允许用户对该帖子再次投票。

在代码中,这个功能对应于投票是否正在提交(submitting)的状态。一般来说,如果一个用户之前没有对某个帖子投票,并且他此时没有在提交对该帖子的投票,那么他就可以对该帖子投票:

exportclassPostextendsComponent{constructor(props){super(props);this

...}

接下来,我们需要更新帖子组件Post的渲染函数render(),以便在用户不能对帖子投票时禁用投票按钮:

render(){..

...}

在进行投票时,我们在发送投票所在的交易之前要先将正在提交状态submitting设置为是(true),并在交易完成后再将其改为否(false),由于此时已经完成了对帖子的投票,因此能否投票状态canVote也应该被设置为否(false):

asyncvote(ballot){..

Bingo!运行一下代码看看效果吧!

一些建议

上述所实现的功能只是百度贴吧提供功能的冰山一角,因此,我们还可以在很多地方做出改进和优化,以下是我的一些建议:

按照反向的时间顺序对帖子进行排序,以便最新提交的帖子始终位于页面顶部;

通过智能合约事件实现帖子列表的重新加载;

引入路由,以便不同用户在创建和查看帖子时有不同的视图;

使用CSS来美化应用程序的视图;

通过使用IPFS和智能合约组合开发一款去中心化应用并不是难事,更多功能等你去挖掘哟。

GitHub地址:

https://github.com/embark-framework/dreddit-tutorial

原文地址:

1、SettinguptheprojectandimplementingaSmartContract

https://embark.status.im/news/2019/02/04/building-a-decentralized-reddit-with-embark-part-1/

2、TestingtheSmartContractthroughEmbarkJS

https://embark.status.im/news/2019/02/11/building-a-decentralized-reddit-with-embark-part-2/

3、Buildingasimplefront-endusingReact

https://embark.status.im/news/2019/02/18/building-a-decentralized-reddit-with-embark-part-3/

标签:POSTPOSOSTREAOutpostcpos币官网FROSTYFLOKI币Protectors of the Realm

以太坊价格今日行情热门资讯
数秦陈豪鸣:在区块链世界,信息流完全等于资金流

7月5日下午,在巴比特举办的“守护数字资产安全”闭门研讨会上,币看高级总监程遥指出,除了事后对被盗资产的追踪,事前的保护措施也是非常重要的.

1900/1/1 0:00:00
以太坊暗网? 这群北大才子做到了...

说到比特币暗网,你能想到什么?丝绸之路、华尔街市场、贩、杀人、情色交易,一直以来,这些都是经常被人诟病的一面。但事物都有两面性,“暗”的另一面,是对现实世界的真实解决方案,是利用“暗”的特性解决当前存在的某个痛点.

1900/1/1 0:00:00
人民银行金融研究所前所长姚余栋:数字货币只是法币的有效补充,不会取代法币

据财经网消息,7月7日,在2019中国财富论坛上,大成基金副总经理兼首席经济学家、人民银行金融研究所前所长姚余栋表示,科技创新是无法阻挡的,数字货币只是法币的有效补充,不会取代法币。这是全球人类经济发展的一个必然需求.

1900/1/1 0:00:00
前法国央行副行长:央行应发行自己的数字货币

2019年7月3日02:07前法国央行副行长让-皮埃尔?朗多为英国《金融时报》撰稿数字化改变了我们沟通、组织、互动、移动和贸易的方式。如今数字化正在改变货币.

1900/1/1 0:00:00
关于ZT即将上线BRC(贝尔链)的公告

尊敬的ZT用户: ZT即将上线BRC,将于2019年7月8日14:00开放BRC充值,7月10日14:00开启BRC/USDT交易对,7月12日14:00开放BRC提币.

1900/1/1 0:00:00
IZICHAIN 7月5日隆重登陆ZBG

IZICHAIN将于2019年7月5日21:00登陆ZBG平台,为了迎合市场热度,特联合ZBG推出双重活动!会员开户即领取糖果大礼包,交易大赛好礼送不停! ZBG交易所概况: ZBG是ZB.COM推动创建的全球化创新币种交易平台.

1900/1/1 0:00:00