我目前在显示用户写入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>
);
}
}
答案 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>
);
}
}