I have a form set up with React Class Components. I want to take the values input by the user and send them to another file. These values will be parameters of an external function call. The values I can console these values declared as constants in the handleSubmit() function but do not know how to export them
import React, {Component} from 'react';
import "./styles.css";
class TokenForm extends React.Component {
constructor(props) {
super(props);
this.state = {
daoName: '',
tokenName: '',
tokenSymbol: '',
daoCap: '',
minEth: '',
maxEth: '',
mintRate: '1000'
};
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
handleSubmit(event) {
event.preventDefault();
const dName = event.target.daoName.value;
const tName = event.target.tokenName.value;
const tSymbol = event.target.tokenSymbol.value;
const dCap = event.target.daoCap.value;
const mnEth = event.target.minEth.value;
const mxEth = event.target.maxEth.value;
const mRate = event.target.mintRate.value;
console.log(dName, tName, tSymbol, dCap, mnEth, mxEth, mRate)
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<h1>Mint DAO Token</h1>
<p>Customise your token variables below</p>
<input type="text" placeholder="DAO Name" name="daoName" value={this.state.daoName} onChange={this.handleInputChange}/>
<input type="text" placeholder="Token Name" name="tokenName" value={this.state.tokenName} onChange={this.handleInputChange}/>
<input type="text" placeholder="Symbol e.g. ABC" name="tokenSymbol" value={this.state.tokenSymbol} onChange={this.handleInputChange}/>
<input type="number" placeholder="DAO Max Capacity" name="daoCap" value={this.state.daoCap} onChange={this.handleInputChange}/>
<input type="number" placeholder="Minimum Investment Limit (ETH)" name="minEth" value={this.state.minEth} onChange={this.handleInputChange}/>
<input type="number" placeholder="Maximum Investment Limit (ETH)" name="maxEth" value={this.state.maxEth} onChange={this.handleInputChange}/>
<select name="mintRate" value={this.state.mintRate} onChange={this.handleInputChange}>
<option value="1000">1,000</option>
<option value="10000">10,000</option>
<option value="100000">100,000</option>
</select>
<button type="submit">SUBMIT</button>
</form>
);
}
}
export default TokenForm;
Related
I have a problem with my React project, I have an input element like below but I can't edit the text of the input. I just can edit the input text only when I delete the value attribute, but I want a default value for it.
<div className="form-group">
<label>Email:</label>
<input
className="form-input"
type="text"
value="l.h.thuong181#gmail.com"
name="email">
</input>
</div>
If you've an uncontrolled component, you might want to use the defaultValue property instead of value (See this reference)
You can use useRef or defaultValue
import React, { useRef, useEffect } from "react";
const input = useRef();
useEffect(() => {
input.current.value = "l.h.thuong181#gmail.com";
}, []);
<input ref={input} className="form-input" type="text" name="email" />`
Here is a sample code how to use inputs in react
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
Set the default value inside the state object and attach a change handler to the input to capture the changes:
Sample codesandbox: https://codesandbox.io/s/react-basic-class-component-22fl7
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
inputValue: 'l.h.thuong181#gmail.com'
};
}
handleChange = event => {
this.setState({ inputValue: event.target.value }, () =>
console.log(this.state.inputValue)
);
};
render() {
return (
<div className="form-group">
<label>Email:</label>
<input
className="form-input"
type="text"
value={this.state.inputValue}
onChange={this.handleChange}
name="email">
</input>
</div>
);
}
}
In my code, I use a click event on the InterestBox in order to update the appearance of the InterestBox and to change the state of the parent of the parent of InterestBox.
However, when I inspect the element with the React Developer Tools or that I try to send a request to my API, the state.interests is always empty. But, when I log the state in the console, it shows an array with a length of 0, but containing all the proper values.
I tried to find what is wrong with my code, but I think I need an external look to find what is wrong.
import axios from 'axios';
import * as Cookies from 'js-cookie';
import React, { Component } from 'react';
import Button from '../../components/Button';
import Dashboard from '../Dashboard';
import ErrorContainer from '../../components/ErrorContainer';
import InterestList from '../../components/register/InterestList';
export class EditUser extends Component {
constructor(props) {
super(props);
this.state = {loading: true, interests: []}
this.addInterest = this.addInterest.bind(this);
this.logState = this.logState.bind(this);
}
addInterest(id, name) {
console.log('hoppity hippity you parenty')
var mid = 'm' + id;
console.log(this.state.interests[mid] == undefined)
if(this.state.interests[mid] == undefined) {
console.log(this.state);
this.setState((state) => {
state.interests[mid] = name;
return {interests: state.interests}
}, () => {
console.log(JSON.stringify(this.state.interests))
})
} else {
console.log('deleted')
var newInterest = this.state.interests;
delete newInterest[mid]
this.setState({interests: newInterest})
}
console.log(this.state.interests)
}
componentDidMount() {
var token = Cookies.get('token');
axios.get('http://localhost:8000/api/details', {headers: {"Accept": 'application/json', "Authorization": `Bearer ${token}`}}).then(
(success) => {
this.setState({
loading: false,
firstname : success.data.data.user.firstname,
lastname: success.data.data.user.lastname,
email: success.data.data.user.email,
dob: success.data.data.user.dob,
address: success.data.data.user.address,
uinterests: success.data.data.interests
})
}, (error) => {
this.props.history.push('/deconnexion');
}
)
var places = require('places.js');
var placesAutocomplete = places({
appId: "plZJLSHIW8M5",
apiKey: "0eddd2fc93b5429f5012ee49bcf8807a",
container: document.querySelector('#address-input')
});
}
logState() {
console.log(this.state);
}
render() {
return (
<Dashboard loading={this.state.loading}>
<h1 className="title">Modifier mon profil</h1>
<form className="user-form offer-update-form" onSubmit={this.handleSubmit}>
<label>Prénom :</label>
<input type="text" name="firstname" value={this.state.firstname} onChange={this.handleChange}></input> <br />
<label>Nom de famille :</label>
<input type="text" name="lastname" value={this.state.lastname} onChange={this.handleChange}></input> <br />
<label>Email :</label>
<input type="email" name="email" value={this.state.email} onChange={this.handleChange} /><br />
<label>Adresse :</label>
<input type="address" id="address-input" name="address" value={this.state.address} onChange={this.handleChange} /><br />
<label>Date de naissance :</label>
<input type="date" name="dob" value={this.state.dob} onChange={this.handleChange} /><br />
<InterestList alreadyChecked={this.state.uinterests} onClick={this.addInterest} />
<ErrorContainer errors={this.state.errors} />
<Button type="primary">Soumettre les changements</Button>
</form>
<Button type="danger" onClick={this.logState} />
</Dashboard>
)
}
}
export default EditUser
```
```
import React, { Component } from 'react'
import InterestBox from './InterestBox'
import Axios from 'axios'
export class InterestList extends Component {
constructor(props) {
super(props);
this.state = {pinterests: []}
this.pinterestRefs = React.createRef()
this.pinterestRefs.current = [];
}
componentDidMount() {
Axios.get('http://localhost:8000/api/interests')
.then((success) => {
this.setState({pinterests: success.data.data.interests});
})
}
componentDidUpdate(prevProps) {
console.log(JSON.stringify(prevProps));
console.log(JSON.stringify(this.props))
if(this.props.alreadyChecked != prevProps.alreadyChecked) {
this.props.alreadyChecked.forEach((item) => {
this.pinterestRefs.current.forEach((pinterest) => {
if(item == pinterest.props.id) {
console.log(pinterest)
pinterest.handleClick();
}
})
console.log(item)
})
}
console.log(this.pin)
}
render() {
return (
<React.Fragment>
{Object.keys(this.state.pinterests).map((interest, i) => {
var pinterest = this.state.pinterests[interest];
var callbackRef = node => this.pinterestRefs.current[i] = node;
return <InterestBox id={pinterest.id} onClick={this.props.onClick} icon={pinterest.picture_src} title={pinterest.name} ref={callbackRef} />
})}
</React.Fragment>
)
}
}
export default InterestList
```
```
import React, { Component } from 'react'
export class InterestBox extends Component {
constructor(props) {
super(props);
this.images = require('../../img/interests/*.svg');
this.state = {activated: false};
this.interest_box_content = React.createRef();
this.interest_text = React.createRef();
this.handleClick = this.handleClick.bind(this);
this.updateDimensions = this.updateDimensions.bind(this);
}
handleClick() {
console.log('hoppity hippity you clicky')
this.props.onClick(this.props.id, this.props.title);
this.setState(prevState => ({
activated: !prevState.activated
}))
}
updateDimensions() {
console.log((window.getComputedStyle(this.refs.interest_box_content).width))
this.refs.interest_text = (window.getComputedStyle(this.refs.interest_box_content).width)
}
render() {
return (
<div className="column is-one-fifth-desktop is-half-touch">
<div className="interest-box">
<div className="interest-box-adjuster">
<div ref={"interest_box_content"} className={"interest-box-content " + (this.state.activated == true ? 'interest-box-activated' : '')} onClick={this.handleClick}>
<img className="interest-icon" src={this.images[this.props.icon]} style={{'height': '50%'}}></img>
<i className="activated-icon fas fa-check"></i>
<span ref={"interest_text"} className="interest-text">{this.props.title}</span>
</div>
</div>
</div>
</div>
)
}
}
export default InterestBox
```
you have initialized interest as an array using []
but then, you are updating it as a map state.interests[mid] = name;
Note: JS is not type-safe. after the above statement, interests no longer remained an array
That's the reason why on console you are able to see it being populated but with an array length of 0. that's because you are outputting an object now and not an array.
I am new in ReactJS and trying to get the search input box value and store it in a state.
My code:
<form className="search-form" onSubmit={this.handleSubmit}>
<input type="search" name="search" ref={(input) => this.query = input}
placeholder="Search..." />
<button className="search-button" type="submit" id="submit">Go!</button>
</form>
Inside constructor:
this.handleSubmit = this.handleSubmit.bind(this);
And
handleSubmit = e => {
e.preventDefault();
this.setState({search: this.query.value});
console.log(this.state.search) //Returns undefined
e.currentTarget.reset();
}
Any help is highly appreciated.
I would suggest you to use controlled input approach.
state = {
value: null,
}
handleValue = (e) => this.setState({ value: e.target.value });
Then you don't have to use ref.
<input
type="search"
name="search"
onChange={this.handleValue}
placeholder="Search..."
/>
This code may help you:
import React from 'react';
class search extends React.Component{
constructor(props)
{
super(props);
this.state = {value: ''};
this.addValue = this.addValue.bind(this);
this.updateInput = this.updateInput.bind(this);
}
addValue(evt)
{
evt.preventDefault();
if(this.state.value !==undefined)
{
alert('Your input value is: ' + this.state.value)
}
}
updateInput(evt){
this.setState({value: evt.target.value});
}
render()
{
return (
<form onSubmit={this.addValue}>
<input type="text" onChange={this.updateInput} /><br/><br/>
<input type="submit" value="Submit"/>
</form>
)
}
}
export default search;
Problem is when i click on edit button, they fill the text inputs with the previously clicked info. when i check my store, the right object is placed into my editor object. so I don't know what's wrong
import React,{Component} from 'react';
import {get_contact, update_contact} from '../actions/';
import {connect} from 'react-redux';
class Edit extends Component {
constructor(props){
super(props);
this.state = {// constructor and initialization of my state
namex: '',
emailx: '',
phonex: '',
idx: ''
}
this.nameInput = React.createRef();
this.emailInput = React.createRef(); //creating references for inputs
this.phoneInput = React.createRef();
}
componentDidMount(){
let id_1 =this.props.location.id;
this.props.get_contact(id_1);
const {id,name, email, phone} = this.props.edits;
this.setState({
namex: name,
emailx: email, //fetching info from props
phonex: phone,
idx: id
})
}
submit_handler = (e) => {
e.preventDefault();
this.setState({
name: this.nameInput.current.value,
email: this.emailInput.current.value,// accessing input values
phone: this.phoneInput.current.value
})
// this.props.update_contact(this.state);
// this.setState({
// name: '',
// email: '',
// phone: '',
// id: ''
// }) console.log(this.state)
} render(){
const {id,namex, emailx, phonex} = this.state;
return (
<div>
<div className = "ml-20 mt-10 " style = {{width: '500px', marginLeft: '400px',marginTop: '80px'}}>
<h3 className="display-4 text-center">Edit Contacts </h3>
<form onSubmit = {this.submit_handler.bind(this)}>
<div className = "form-group">
<label htmlFor ="Names">Names</label>
<input className="form-control" type="text" name="name" defaultValue={namex} ref = {this.nameInput}/>
</div>
<div className = "form-group">
<label htmlFor="email">Email</label>
<input className="form-control" type="email" name="email" defaultValue={emailx} ref = {this.emailInput}/>
</div>
<div className = "form-group">
<label htmlFor="contact">Contact</label>
<input className="form-control" type="text" name="phone" defaultValue={phonex} ref = {this.phoneInput} />
</div>
<div className = "form-group">
<input className="btn btn-primary btn-block" type="submit" name="editor" value="Edit" />
</div>
</form>
</div>
</div>
) } } const mapStateToProps = (state) => ({ edits: state.Users.editor }) export default connect(mapStateToProps, {get_contact,update_contact})(Edit);
I'm trying to make reusable Form and Input components and so far got to following:
Form
import React from 'react'
import classNames from 'classnames/bind'
import styles from './style.scss'
const cx = classNames.bind(styles)
export default class Form extends React.Component {
constructor (props) {
super(props)
this.submitForm = this.submitForm.bind(this)
}
submitForm (e) {
e.preventDefault()
this.props.onSubmit()
}
render () {
return (
<form className={cx('Form')} onSubmit={this.submitForm}>
{this.props.children}
</form>
)
}
}
Form.propTypes = {
children: React.PropTypes.any.isRequired,
onSubmit: React.PropTypes.func.isRequired
}
Input
import React from 'react'
import classNames from 'classnames/bind'
import styles from './style.scss'
const cx = classNames.bind(styles)
export default class Input extends React.Component {
constructor (props) {
super(props)
this.state = {
value: this.props.value || ''
}
this.changeValue = this.changeValue.bind(this)
}
changeValue (e) {
this.setState({value: e.target.value})
}
render () {
return (
<div className={cx('Input')}>
<input
type={this.props.type}
value={this.state.value}
required={this.props.required}
onChange={this.changeValue}
placeholder={this.props.placeholder || ''}
noValidate />
</div>
)
}
}
Input.propTypes = {
type: React.PropTypes.string.isRequired,
value: React.PropTypes.string,
required: React.PropTypes.bool,
placeholder: React.PropTypes.string
}
I then use them within some another component, lets say HomePageComponent
<Form onSubmit={this.loginUser}>
<Input type='email' placeholder='email' />
<Input type='password' placeholder='password' />
<Input type='submit' value='Submit' />
</Form>
This all works well, but how would I get input values and use them to set state of HomePageComponent to this.state= { email: [value from input email], password: [value from password input] }
You don't need to store the value in the Input component.
You can get the input values by keeping references to individual inputs:
<Form onSubmit={this.loginUser}>
<Input ref='email' type='email' placeholder='email' />
<Input ref='password' type='password' placeholder='password' />
<Input type='submit' value='Submit' />
</Form>
Then, in loginUser you can access these using:
const email = ReactDOM.findDOMNode(this.refs.email).value;
const password = ReactDOM.findDOMNode(this.refs.password).value;
if you add the name attribute to your input elements, you can access their values this way. Hope this helps
import React, { PropTypes, Component } from 'react';
class Form extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e) {
e.preventDefault();
const form = e.target.elements;
console.log(form.email.value);
console.log(form.password.value);
}
render() {
return (
<form className={cx('Form')} onSubmit={this.handleSubmit}>
<Input type='email' placeholder='email' name='email' />
<Input type='password' placeholder='password' name='password' />
<button type="submit">Submit</button>
</form>
);
}
}