Reputation: 11
I am currently trying to get the complete input from a user in a form using React. I need to get these inputs and then store them so that I can pass these values to another function. Currently, I have been trying to use uncontrolled inputs without success, but have also tried controlled inputs without any success either. Any ideas? I have to pass these values to the function peopleContract.addPerson(this._firstName, this._lastName, this._email, {from: accounts[1], gas: 3000000})
Here is the code (commented is the controlled input approach):
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 = '0xb1a711f4e1250761b85be7bb4478c07d256b8225'
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{
handleSubmitClick = () => {
const firstName = this._firstName.value;
const lastName = this._lastName.value;
const email = this._email.value;
//do something with these variables
}
/*
handleChange(event) {
this.setState({[key]: event.target.value});
}
*/
/*
handleChange(event) {
this.setState({[event.target.name]: event.target.value});
}
handleSubmit(event) {
alert('A user was submitted: ' + this.state.firstName + this.state.lastName + this.state.email);
event.preventdefault();
*/
/*
if((this.state.firstName==!"") && (this.state.lastName==!"")&& (this.state.email==!"")){
peopleContract.addPerson(this.state.firstName, this.state.lastName, this.state.email, {from: accounts[1], gas: 3000000})
// after you subimt values clear state
this.setState({
firstName: this.state.firstName,
lastName: this.state.lastName,
email: this.state.email
})
}else{
// render error
alert('Some fields are mandatory');
}
}
*/
/*
componentWillMount(){
peopleContract.addPerson(this._firstName, this._lastName, this._email, {from: accounts[1], gas: 3000000})
}
*/
render() {
peopleContract.addPerson(this._firstName, this._lastName, this._email, {from: accounts[1], gas: 3000000})
return(
<form>
<div>
<h4>Name</h4>
<input
type="text"
ref={input => this._firstName = input} />
</div>
<div>
<h4>Last Name</h4>
<input
type="text"
ref = {input2 => this._lastName = input2} />
</div>
<div>
<h4>Email</h4>
<input
type="text"
ref = {input3 => this._email = input3} />
</div>
<button onClick={this.handleSubmitClick}>Submit</button>
</form>
);
}
}
Upvotes: 0
Views: 82
Reputation: 104369
By using ref callback we store the reference of dom element, As per DOC:
When the ref attribute is used on an HTML element, the ref callback receives the underlying DOM element as its argument. For example, this code uses the ref callback to store a reference to a DOM node:
ref = { (input) => { this.textInput = input; }} />
To get the values of uncontrolled component using ref you need to write:
this._firstName.value, //value
this._lastName.value, //value
this._email.value //value
Another change is remove this line from render method:
peopleContract.addPerson(this._firstName, this._lastName, this._email, {from: accounts[1], gas: 3000000})
Because during initial rendering ref will not be available, so it you try to access the value before rendering it will throw error.
The ref attribute takes a callback function, and the callback will be executed immediately after the component is mounted or unmounted.
Check the working solution:
class Form extends React.Component{
handleSubmitClick() {
const firstName = this._firstName.value;
const lastName = this._lastName.value;
const email = this._email.value;
console.log(firstName, lastName,email);
peopleContract.addPerson(firstName, lastName, email, {from: accounts[1], gas: 3000000})
}
render() {
return(
<form>
<div>
<h4>Name</h4>
<input
type="text"
ref={input => this._firstName = input} />
</div>
<div>
<h4>Last Name</h4>
<input
type="text"
ref = {input2 => this._lastName = input2} />
</div>
<div>
<h4>Email</h4>
<input
type="text"
ref = {input3 => this._email = input3} />
</div>
<button onClick={this.handleSubmitClick.bind(this)}>Submit</button>
</form>
);
}
}
ReactDOM.render(<Form/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'/>
Upvotes: 0
Reputation: 746
You are trying to use the refs before they are assigned in the render function.
It seems like you want to call peopleContract.addPerson()
on submit so it should look like this
export class Form extends React.Component{
handleSubmitClick = () => {
const firstName = this._firstName.value;
const lastName = this._lastName.value;
const email = this._email.value;
peopleContract.addPerson(firstName, lastName, email, {from: accounts[1], gas: 3000000})
}
render() {
return(
<form>
<div>
<h4>Name</h4>
<input
type="text"
ref={input => this._firstName = input} />
</div>
<div>
<h4>Last Name</h4>
<input
type="text"
ref = {input2 => this._lastName = input2} />
</div>
<div>
<h4>Email</h4>
<input
type="text"
ref = {input3 => this._email = input3} />
</div>
<button onClick={this.handleSubmitClick}>Submit</button>
</form>
);
}
}
Upvotes: 1