Dapp 眾籌專案(5)

2020-10-28 20:01:07

1.對三個子介面的實現

---所有的眾籌專案---我建立的眾籌專案---我參加的眾籌專案

import React,{Component} from "react";
import {getFundingDetails}from '../../eth/interaction'
import CardList from "../common/CardList";
class AllFundingTab extends Component{
    state ={
        allFundingDetails :[],
    }
    //在componentWillMount方法中獲取我發起的眾籌,並設定到state中。
    async componentWillMount() {
        let allFundingDetails=await getFundingDetails(1)
        console.table('1',allFundingDetails)
        this.setState({
            allFundingDetails
        })
    }
//在render方法中從state獲取資料。
    render(){
        return(
            <CardList details={this.state.allFundingDetails}/>
        )
    }
}
export default AllFundingTab

三個介面所實現的功能是一樣的,所以複製黏貼並更改獲取不同功能的函數

現在我們來看看結果吧!!!

2.搭建發起眾籌表單

程式碼使用到了semantic-ui的form元件。具體可以參考:https://react.semantic-ui.com/collections/form/

import React, {Component} from 'react';
import {Dimmer, Form, Label, Loader, Segment} from 'semantic-ui-react'
//import {createFunding} from "../eth/interaction";
class CreateFundingForm extends Component {
    // 定義狀態變數
    state = {
        active: false,
        projectName: '',
        supportMoney: '',
        targetMoney: '',
        duration: '',
    }

    render() {
        let {active, projectName, targetMoney, supportMoney, duration} = this.state

        return (
            <div>
                <Dimmer.Dimmable as={Segment} dimmed={active}>
                    <Dimmer active={active} inverted>
                        <Loader>Loading</Loader>
                    </Dimmer>
                    <Form onSubmit={this.handleCreate}>
                        <Form.Input required type='text' placeholder='專案名稱' name='projectName'
                                    value={projectName} label='專案名稱:'
                                    onChange={this.handleChange}/>

                        <Form.Input required type='text' placeholder='支援金額' name='supportMoney'
                                    value={supportMoney} label='支援金額:'
                                    labelPosition='left'
                                    onChange={this.handleChange}>
                            <Label basic>¥</Label>
                            <input/>
                        </Form.Input>

                        <Form.Input required type='text' placeholder='目標金額' name='targetMoney' value={targetMoney}
                                    label='目標金額:'
                                    labelPosition='left'
                                    onChange={this.handleChange}>
                            <Label basic>¥</Label>
                            <input/>
                        </Form.Input>
                        <Form.Input required type='text' placeholder='眾籌時間' name='duration' value={duration}
                                    label='眾籌時間:'
                                    labelPosition='left'
                                    onChange={this.handleChange}>
                            <Label basic>S</Label>
                            <input/>
                        </Form.Input>
                        <Form.Button primary content='建立眾籌'/>
                    </Form>
                </Dimmer.Dimmable>
            </div>
        )
    }
}

export default CreateFundingForm

檢視頁面結果:

3.與from表單互動

定義表單項的onchange事件函數,該函數把表單項的值設定到狀態變數中

handleChange =(e,{name,value}) =>this.setState({[name]:value})

然後寫一個函數來看看是否觸發了按鈕:

handleCreate = () =>{
        let {active,projectName,targetMoney,supportMoney,duration} =this.state
        console.log('projectName:',projectName)
        console.log('targetMoney:',supportMoney)
    }

看看結果吧!!

4.與以太坊進行互動

定義表單提交函數

  handleCreate = async() =>{
        let {active,projectName,targetMoney,supportMoney,duration} =this.state
        console.log('projectName:',projectName)
        console.log('targetMoney:',supportMoney)
        this.setState({active:true})
        try {
            let res= await createFunding(projectName, targetMoney, supportMoney, duration)
            alert('建立合約成功!\n')
            this.setState({active:false})
        }catch(e){
            this.setState({active:false})
            console.log(e)
        }
    }

在interaction.js檔案中定義createFunding方法,並匯出該方法。

let createFunding = (projectName,targetMoney,supportMoney,duration)=>{
    return new Promise(async (resolve,reject)=>{
    try {//呼叫建立方法
        let accounts =await web3.eth.getAccounts()
        let res = await fundingFactoryInstance.methods.createFunding(projectName, targetMoney, supportMoney, duration).send({
            from: accounts[0],
        })
        resolve(res)
    }catch(e){
        reject(e)
    }
    })
    }

讓我們看看結果吧!!!!!

5.在AllFundingTab新增表單項,在render方法中把狀態變數的資料結構出來

render(){
        return(
            <div>
                <CardList details={this.state.allFundingDetails}/>
                <div>
                    <h3>參與眾籌</h3>
                    <Dimmer.Dimmable as={Segment} dimmed={this.state.active}>
                        <Dimmer active={this.state.active} inverted>
                            <Loader>支援中</Loader>
                        </Dimmer>
                    <Form onSubmit={this.handleInvest}>
                        <Form.Input type='text' value={''} label='專案名稱:'/>
                        <Form.Input type='text' value={''} label='專案地址:'/>
                        <Form.Input type='text' value={''} label='支援金額:'
                                labelPosition='left'>
                            <Label basic>¥</Label>
                            <input/>
                        </Form.Input>
                        <Form.Button primary content='參與眾籌'/>
                    </Form>
                    </Dimmer.Dimmable>
                </div>
            </div>

    )
    }

給card新增一個onClick方法,就可以點選影象專案,返回這個專案的詳細資訊

在card中設定一個回撥函數,這個回撥函數在AllFundingTab實現,通過props逐層傳給Card

點選Card時,將card的詳細資訊通過回撥函數返回給主介面AllFundingTab,從而完成資料的獲取

將返回的detail設定到狀態變數中,展示在介面

發起參與眾籌

    let onCardClick =props.onCardClick

<Card onClick={()=> onCardClick(detail2)}>

 onCardClick =(selectedFundingDetail)=>{
        console.log("bbb:",selectedFundingDetail)

<CardList details={this.state.allFundingDetails}onCardClick={this.onCardClick}/>

【通過allFundingTab建立一個函數OncardClick,然後通過cardlist傳遞給props,Props再傳遞給cardfunding,

再給card,返回detail2,最後在主介面拿到即可】

6將拿到的資料展示到頁面

        a.為了展示到頁面,引入seletedFundingDetail狀態變數

             處理投資函數//需要傳遞選中合約地址 //建立合約範例,發起參與眾籌(send,value轉錢)

//建立合約範例 //填充地址  //執行投資

let handleInvestFunc = async (fundingAddress,supportMoney) =>{

    try {//建立合約範例
        let fundingInstance = newFundingInstance()
        //填充地址
        fundingInstance.options.address = fundingAddress
        //執行投資
        let accounts = await web3.eth.getAccounts()
        let res = await fundingInstance.methods.invest().send({
            from: accounts[0],
            value: supportMoney,
        })
        return res
    }catch(e){
        throw e
    }

}