React JS + Solidity:逐字输出而不是全字输入

时间:2017-07-12 00:07:20

标签: reactjs react-redux ethereum solidity

我目前在显示用户写入Web应用程序的输入时遇到问题。输出显示为逐字母而不是整个单词。我的怀疑是我在渲染()内部做错了什么,但我不知道问题。代码如下(还有一个可靠的智能合约,我称之为几个函数)。问题在于Form.js:

智能合约(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. bobstark@gmail.com"
            value={this.state.email}
            onChange={event => this.handleChange(event, 'email')}/>
        </div>
        <input
          type = "submit"
          name = "Submit"
          />
      </form>
    );
  }
}

1 个答案:

答案 0 :(得分: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. bobstark@gmail.com"
            value={this.state.email}
            name = "email"
            onChange= {this.handleChange}  />
        </div>
        <input
          type = "submit"
          name = "Submit"
          />
      </form>
    );
  }
}