2017-07-12 66 views
0

我目前有一個問題,顯示用戶寫入Web應用程序的輸入。輸出逐字符而不是整個單詞顯示。我的懷疑是我在render()內部做了錯誤,但我不知道這個問題。代碼如下(還有一個可靠的智能合約,我稱之爲幾個函數)。問題是與Form.js:React JS + Solidity:逐字輸出而不是全字輸入

智能合同(People.sol)

pragma solidity ^0.4.2; 
contract People{ 

//array of all the people in our system 
Person[] public people; 

    struct Person{ 
    bytes32 firstName; 
    bytes32 lastName; 
    bytes32 email; 
} 

    function addPerson(bytes32 _firstName, bytes32 _lastName, bytes32 _email) returns (bool success){ 

    Person memory newPerson; //memory where it can store state variables, carving out memory for a new Person 
    newPerson.firstName = _firstName; 
    newPerson.lastName = _lastName; 
    newPerson.email = _email; 

    //Once pushed, it costs gas 
    people.push(newPerson); //This adding element to array, once added to array saved to blockchain 
    return true; 

    } 
    // Constant function not changing state 
    // Solidity doesn't return structs, so need to put them in strings 
    // Need to do an array for each separate attribute, have an array of 
    // Problem with solidity is that you need strings of the same length 
    // So that the array that is made is correct 
    // If you are returning a constant, you can loop as much as you want without spending more gas 
    function getPeople() constant returns (bytes32[], bytes32[], bytes32[]) { 

    uint length = people.length; 

    bytes32[] memory firstNames = new bytes32[](length); 
    bytes32[] memory lastNames = new bytes32[](length); 
    bytes32[] memory email = new bytes32[](length); 

    for (uint i = 0; i < people.length; i++) { 
     Person memory currentPerson; 
     currentPerson = people[i]; 

     firstNames[i] = currentPerson.firstName; 
     lastNames[i] = currentPerson.lastName; 
     email[i] = currentPerson.email; 
     } 
     return(firstNames,lastNames,email); 
    } 
} 

App.js

import React, { Component } from 'react'; 
import logo from './logo.svg'; 
import dxclogo from './dxclogo.png'; 
import './App.css'; 
import Web3 from 'web3'; 
import _ from 'lodash' 
import { Form } from './Form'; 

//Declaring the ethereum client (initializing) with the url in which the testrpc is running 
var ETHEREUM_CLIENT = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) 

//These could be dynamically added through input fields, but hard coding for now 
var peopleContractABI = [{"constant":true,"inputs":[],"name":"getPeople","outputs":[{"name":"","type":"bytes32[]"},{"name":"","type":"bytes32[]"},{"name":"","type":"bytes32[]"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"people","outputs":[{"name":"firstName","type":"bytes32"},{"name":"lastName","type":"bytes32"},{"name":"email","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_firstName","type":"bytes32"},{"name":"_lastName","type":"bytes32"},{"name":"_email","type":"bytes32"}],"name":"addPerson","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"}] 

var peopleContractAddress = '0xa0b4dccf81cb4bc6cdb890637dc02b62a7a35b66' 

var peopleContract = ETHEREUM_CLIENT.eth.contract(peopleContractABI).at(peopleContractAddress) 

class App extends Component{ 
    constructor(props){ 
    super(props); 
    this.state = { 
     firstNames: [], 
     lastNames: [], 
     emails: [] 
    } 
    } 

    componentWillMount(){ 
    var data = peopleContract.getPeople() 
    this.setState({ 
     firstNames: String(data[0]).split(','), 
     lastNames: String(data[1]).split(','), 
     emails: String(data[2]).split(',') 
    }) 
    } 

    render() { 
    var TableRows = [] 

    _.each(this.state.firstNames, (value, index) => { 
    TableRows.push(
     <tr> 
     <td>{ETHEREUM_CLIENT.toAscii(this.state.firstNames[index])}</td> 
     <td>{ETHEREUM_CLIENT.toAscii(this.state.lastNames[index])}</td> 
     <td>{ETHEREUM_CLIENT.toAscii(this.state.emails[index])}</td> 
     </tr> 
    ) 
    }) 

    return (
     <div className="App"> 
     <div className="App-header"> 
      <img src={logo} className="App-logo" alt="logo" /> 
      <img src = {dxclogo} className ="App-dxclogo" alt="dxclogo" /> 
      <h1>Hotel Room Booking dApp</h1> 
     </div> 
     <div> 
      <Form /> 
      <table className="App-tablePeople"> 
      <thead> 
       <tr> 
       <th>First Name </th> 
       <th>Last Name </th> 
       <th>Email </th> 
       </tr> 
      </thead> 
      <tbody> 
       {TableRows} 
      </tbody> 
      </table> 
     </div> 
     </div> 
    ); 
    } 
} 

export default App; 

Form.js

import React from 'react'; 
import Web3 from 'web3'; 

//Declaring the ethereum client (initializing) with the url in which the testrpc is running 
var ETHEREUM_CLIENT = new Web3(new Web3.providers.HttpProvider("http://localhost:8545")) 

//These could be dynamically added through input fields, but hard coding for now 
var peopleContractABI = [{"constant":true,"inputs":[],"name":"getPeople","outputs":[{"name":"","type":"bytes32[]"},{"name":"","type":"bytes32[]"},{"name":"","type":"bytes32[]"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"people","outputs":[{"name":"firstName","type":"bytes32"},{"name":"lastName","type":"bytes32"},{"name":"email","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_firstName","type":"bytes32"},{"name":"_lastName","type":"bytes32"},{"name":"_email","type":"bytes32"}],"name":"addPerson","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"}] 

var peopleContractAddress = '0xa0b4dccf81cb4bc6cdb890637dc02b62a7a35b66' 

var peopleContract = ETHEREUM_CLIENT.eth.contract(peopleContractABI).at(peopleContractAddress) 

//Need to create a variable named accounts in order to know which account 
//to make the transactions from 
var accounts = ETHEREUM_CLIENT.eth.accounts 

//Creating the dynamic input fields for the user to input his/her data 
export class Form extends React.Component{ 
    constructor(props){ 
    super(props); 
    this.state = { 
    firstName: "", 
    lastName: "", 
    email: "", 
    } 

    this.handleChange = this.handleChange.bind(this); 
    this.handleSubmit = this.handleSubmit.bind(this); 
    } 

    handleChange(event, key) { 
    this.setState({[key]: event.target.value}); 
    } 

    handleSubmit(event) { 
    alert('A user was submitted: ' + this.state.firstName + this.state.lastName + this.state.email); 
    event.preventdefault(); 
    } 


/*Creating so that person can be added 
    componentWillMount(){ 
    this.setState({ 
     firstName: this.state.firstName, 
     lastName: this.state.lastName, 
     email: this.state.email 
    }) 
} 
*/ 

    render() { 
    peopleContract.addPerson(this.state.firstName, this.state.lastName, this.state.email, {from: accounts[1], gas: 3000000}) 
    return(
     <form onSubmit={this.handleSubmit}> 
     <h4>Name</h4> 
     <input 
      type="text" 
      placeholder="e.g. Bob" 
      value={this.state.firstName} 
      onChange={event => this.handleChange(event, 'firstName')} /> 
     <div> 
     <h4>Last Name</h4> 
      <input 
      type="text" 
      placeholder="e.g. Stark" 
      value={this.state.lastName} 
      onChange={event => this.handleChange(event, 'lastName')}/> 
     </div> 
     <div> 
     <h4>Email</h4> 
      <input 
      type="text" 
      placeholder="e.g. [email protected]" 
      value={this.state.email} 
      onChange={event => this.handleChange(event, 'email')}/> 
     </div> 
     <input 
      type = "submit" 
      name = "Submit" 
      /> 
     </form> 
    ); 
    } 
} 

回答

0

render函數獲取每次更新表格都要叫,所以你可能不想要這行

peopleContract.addPerson(this.state.firstName, this.state.lastName, this.state.email, {from: accounts[1], gas: 3000000}) 

您的渲染功能。

handleChange函數內部,您可以使用文本輸入的name屬性來確定哪個文本輸入已更改。

handleChange: function(e) { 
     this.setState({[e.target.name]: e.target.value}); 
    } 


    render() { 
    peopleContract.addPerson(this.state.firstName, this.state.lastName, this.state.email, {from: accounts[1], gas: 3000000}) 
    return(
     <form onSubmit={this.handleSubmit}> 
     <h4>Name</h4> 
     <input 
      type="text" 
      placeholder="e.g. Bob" 
      value={this.state.firstName} 
      name = "firstName" 
      onChange= {this.handleChange} /> 
     <div> 
     <h4>Last Name</h4> 
      <input 
      type="text" 
      placeholder="e.g. Stark" 
      value={this.state.lastName} 
      name = "lastName" 
      onChange= {this.handleChange} /> 
     </div> 
     <div> 
     <h4>Email</h4> 
      <input 
      type="text" 
      placeholder="e.g. [email protected]" 
      value={this.state.email} 
      name = "email" 
      onChange= {this.handleChange} /> 
     </div> 
     <input 
      type = "submit" 
      name = "Submit" 
      /> 
     </form> 
    ); 
    } 
} 
+0

然而,這會打印整個單詞而不是逐字?我相信我沒有別的選擇,只能在渲染函數中放置'peopleContract.addPerson(this.state.firstName,this.state.lastName,this.state.email,{from:accounts [1],gas:3000000})''從我試過的... – jh5614

+0

對不起。我對固體不熟悉。幫不了那個部分。你可以在render函數裏放一個'console.log'語句來檢查它何時被調用。 – snwclone

相關問題