ReactJS: ReferenceError: submitClick is not defined - reactjs

I have gone through the solutions provided regarding this problem but i still have the problem.
This is my simple code
<button onClick={submitClick} id="SubmitBtn">Request Invite</button>
then in the index.js file i have this function: which is meant to execute onClick on the submit button.
function submitClick() {
window.alert("JEBE");
}
Please help.

Please bind the function in the constructor
class App extends React.Component {
constructor(props){
super(props);
this.state={
value:""
}
this.submitClick = this.submitClick.bind(this);
this.change = this.change.bind(this);
}
change(e){
this.setState({
value : e.target.value
});
}
submitClick(){
alert(this.state.value);
}
render() {
return <div>
<form>
Email <input id="MainEmail" type="email"
placeholder ="Enter your email"
onChange={this.change}
/>
<button onClick={this.submitClick}
id="SubmitBtn">Request Invite
</button>
</form>
<br/><br/>
</div>;
}
}
ReactDOM.render(
<App />,
document.getElementById('container')
);
<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="container">
</div>

Try using:
<button onClick={this.submitClick} id="SubmitBtn">Request Invite</button>

Related

setState called everytime I type something in input

so i'm facing an issue where whenever I write something in input, handleCommentAdded is called which calls setState, re-rendering everything. This makes everything that is typed or was typed in the input to appear as comments and i want what is in the input when I click submit to appear as comment. How can I fix this?
class WriteComments extends React.Component {
constructor(props) {
super(props);
this.state = {
commentAdded:"",
}
this.handleButton = this.handleButton.bind(this);
this.handleCommentAdded = this.handleCommentAdded.bind(this);
}
handleCommentAdded(event) {
this.setState({newComment: event.target.value});
}
handleButton() {
return(
<div>
{comment}
</div>
)
}
render() {
return(
<div>
<input type="text" value={this.state.commentAdded} onChange=
{this.handleCommentAdded}/>
<div className="button">
<button
type="button"
onClick={e => this.handleButton(e)}
>
Write
</button>
</div>
)
}
}
Error is calling handleCommentAdded on onChange
set state in handleButton
class WriteComments extends React.Component {
constructor(props) {
super(props);
this.state = {
commentAdded: ""
};
this.inputRef = React.createRef();
this.handleButton = this.handleButton.bind(this);
}
handleButton() {
this.setState({ commentAdded: this.inputRef.current.value });
}
render() {
return (
<div>
<input type="text" ref={this.inputRef} />
<div className="button">
{this.state.commentAdded !== "" ? (
<div>{this.state.commentAdded}</div>
) : (
<button type="button" onClick={e => this.handleButton(e)}>
Write
</button>
)}
</div>
</div>
);
}
}
ReactDOM.render(<WriteComments />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root' />
I created a demo where textfield value can be get by button click. Component will render everytime when setState calls. Hope it can help you!
class App extends React.Component{
state ={ inputValue:"" };
render(){
return(
<div>
<input type="text" value={this.state.inputValue} onChange={this.handleChange} />
<button onClick={this.handleSubmit}>Submit</button>
</div>
);
}
handleChange=(e)=>{
this.setState({ inputValue: e.target.value });
}
handleSubmit=()=>{
console.log("inputValue::", this.state.inputValue);
}
}
ReactDOM.render(<App/>, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Value of Form Input not updating on Submit in React

I am new to React and writing a basic program where using two input fields and a button I want to show the submitted data through another component.
I have declared state in the App component and used a handleChange and handleSubmit method. I have used this state data as props in Display component. But I am getting the data shown when input changes and not on submit.
Have a look at my code:
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(){
super();
this.state={
first:'',
last:''
}
this.handleChange=this.handleChange.bind(this);
//this.handleSubmit=this.handleSubmit.bind(this);
}
//handleChange method will capture the change in the values of input field
//Here [e.target.name]:e.target.value will set the input value to name="first" and name="last"
handleChange(e){
this.setState({
[e.target.name]:e.target.value
});
}
handleSubmit(e){
e.preventdefault();
this.handleChange();
}
render() {
return (
<div className="App">
<div class="row">
<input name="first" onChange={this.handleChange}type="text" value={this.state.first}></input>
</div>
<div class="row">
<input name="last" onChange={this.handleChange}type="text" value={this.state.last}></input>
</div>
<div class="row">
<input name="submit" type="button" onSubmit={this.handleSubmit}></input>
</div>
<Display name={this.state.first} last={this.state.last}/>
</div>
);
}
}
const Display=(props)=>{
return(
<div>
<div class="row">
{props.name}
</div>
<div class="row">
{props.last}
</div>
</div>
)
}
export default App;
Also can somebody explain me why do we write [e.target.name]:e.target.value
in setState and why do we right it as []?
The handleChange function that you have used sets the state to first and last states respectively when they change. This pattern is called Controlled Components in React.
On why we use [] in the handleChange function, as you have already pointed out in comments of your code, it is to set the state to first and last, which are also name properties of your inputs. This syntax is called Computed Property and you can find explanation on this in React docs.
If you want the Display component to pick up the state only when you press submit, the alternative is to maintain two separate states for them. One is for the form and another one is for the validated one that is displayed.
Demo:
const { Component } = React;
class App extends Component {
constructor(){
super();
this.state={
first:'',
last:''
}
this.handleSubmit=this.handleSubmit.bind(this);
}
handleSubmit(first, last){
this.setState({
first,
last,
})
}
render() {
return (
<div className="App">
<Form onSubmit={this.handleSubmit} />
<Display name={this.state.first} last={this.state.last}/>
</div>
);
}
}
class Form extends Component {
constructor(){
super();
this.state={
first:'',
last:''
}
this.handleChange=this.handleChange.bind(this);
this.handleSubmit=this.handleSubmit.bind(this);
}
handleChange(e){
this.setState({
[e.target.name]:e.target.value
});
}
handleSubmit(e) {
e.preventDefault();
this.props.onSubmit(this.state.first, this.state.last);
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<div className="row">
<input name="first" onChange={this.handleChange}type="text" value={this.state.first} />
</div>
<div className="row">
<input name="last" onChange={this.handleChange}type="text" value={this.state.last} />
</div>
<div className="row">
<input name="submit" type="submit" />
</div>
</form>
);
}
}
const Display=(props)=>{
return(
<div>
<div className="row">
{props.name}
</div>
<div className="row">
{props.last}
</div>
</div>
)
}
ReactDOM.render(<App />, document.getElementById("root"));
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<div id="root"></div>

How to get data from Form from child component and pass it back to Parent Componet? [duplicate]

This question already has answers here:
How to access a DOM element in React? What is the equilvalent of document.getElementById() in React
(9 answers)
Closed 5 years ago.
I want to add items to the lists.Items come from Child Component's form .
class App extends Component {
constructor(props) {
super(props);
this.state = {
lists: [], // this holds the name of each list
};
}
handleAddList(s) {
this.setState({lists:s});
};
render() {
return (
<div className="App">
<AddList addList={this.handleAddList.bind(this)} />
</div>
);
}
}
What should I write in handleSubmit function such that it return list to parent component?How to access input's value from form element?
class AddList extends Component {
handleSubmit(e) {
e.preventDefault();
this.props.addList(e.target.value); //Isn't this the way to get input from Form ...//
}
render() {
return (
<div id="addListDiv">
<form onSubmit={this.handleSubmit.bind(this)}>
<div id='addList'>
<label>What will be on your next list?
<input type='text' ref='id' id='newID'></input> //How ref is used?????
</label>
</div><br />
<input type='submit' value='Create List' />
</form>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root'));
To access your input value by ref you can use this.refs.id.value and to pass value from child to parent component you can use props.
let {Component} = React;
class App extends Component {
constructor(props) {
super(props);
this.state = {
lists: [], // this holds the name of each list
};
}
handleAddList(s) {
this.setState(prevState => {
return {lists: [s, ...prevState.lists]}
});
};
render() {
return (
<div className="App">
<AddList addList={this.handleAddList.bind(this)} />
{this.state.lists.map((name, i) => <div key={i}>{name}</div>)}
</div>
);
}
}
class AddList extends Component {
handleSubmit(e) {
e.preventDefault();
let name = this.refs.id.value;
if(name) {
this.refs.id.value = '';
this.props.addList(name);
}
}
render() {
return (
<div id="addListDiv">
<form onSubmit={this.handleSubmit.bind(this)}>
<div id='addList'>
<label>What will be on your next list?
<input type='text' ref='id' id='newID'></input>
</label>
</div><br />
<input type='submit' value='Create List' />
</form>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
<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="root"></div>

All checkbox are checked upon clicking

I'm fairly new to react, and I'm trying to create a simple form. The form app has many elements including the 3 checkbox. And to simplify my issue, I'm only showing the checkboxes. Here what I'm doing
When I click on a checkbox, the value of the label will be pushed
into an array and saved into the App state.
I'm using event.target.name because I have multiple inputs in the
form and I wanted to keep just in case to make my problem more
descriptive.
When I click on submit, it should clear the checkbox.
The problem is when I click on checkbox all the 3 of get checked and it won't be cleared after hitting submit. Is there any way to overcome this? or why its happening?
function CheckBox(props) {
var style= {
padding:10,
marginLeft:5
}
return(
<div style={style} >
{props.checkboxList.map((item,index) =>
<div key={index}>
<input type="checkbox"
onChange={props.changeHandler}
checked={props.checkStatus} name={props.name} value={item.val} />
<label>{item.num}) {item.val}</label>
</div>)}
</div>
)
}
class App extends React.Component{
constructor(props) {
super(props);
this.state={item:[],checked:false}
this.changeHandler=this.changeHandler.bind(this)
this.submitHandler=this.changeHandler.bind(this)
}
changeHandler(event) {
if(event.target.name=="choice") {
var arr=this.state.item.slice()
arr.push(event.target.value)
this.setState({item:arr, checked:event.target.checked}, ()=> console.log(this.state.item +"--"+ this.state.checked))
}
else{ console.log('error')}
}
submitHandler(){
this.setState({item:[],checked:false})
}
render() {
return(
<div>
<CheckBox checkboxList={[
{num:"a", val:"choice 1"},
{num:"b", val:"choice 2"},
{num:"c", val:"choice 3"}]} changeHandler={this.changeHandler} name="choice" checkStatus={this.state.checked} />
<button onClick={this.submitHandler}>Submit</button>
</div>
)
}
}
ReactDOM.render(
<App/>,
document.getElementById("root")
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>
<div id="root"></div>
The main approach is to add state key to the each checkbox:
constructor(props) {
super(props);
this.state={item:[],checked:{}}
this.changeHandler=this.changeHandler.bind(this)
this.submitHandler=this.submitHandler.bind(this)
}
changeHandler(event) {
if(event.target.name=="choice") {
var arr=this.state.item.slice()
arr.push(event.target.value)
this.setState({item:arr, checked:{
...this.state.checked,
[event.target.value]: event.target.checked
}}, ()=> console.log(this.state.item +"--"+ this.state.checked))
}
else{ console.log('error')}
}
submitHandler(){
this.setState({item:[],checked:{}})
}
and for checkbox:
{props.checkboxList.map((item,index) =>
<div key={index}>
<input type="checkbox"
onChange={props.changeHandler}
checked={props.checkStatus[item.val]} name={props.name} value={item.val} />
<label>{item.num}) {item.val}</label>
</div>)}

Is the correct way to access ref in react?

Without using binding of this.say to this on button the example does not work. However I am not sure if it is right or has any side effects.
class Speak extends React.Component {
render() {
return (
<div>
<input ref={(c) => this._input = c} defaultValue="Hello World!"/>
<button onClick={this.say.bind(this) }>Say</button>
</div>
);
}
say() {
if (this._input !== null) {
alert(this._input.value);
}
}
};
ReactDOM.render(<Speak />, 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" />
Seems like this is required when using ES6 classes: See: Autobinding
Only difference is example above binds the method in constructor
you can utilize array functions and forget about adding .bind(this)
check out working pen
class Speak extends React.Component {
render() {
return (
<div>
<input type='text' ref='greeting'/>
<button onClick={this.say}>Say</button>
</div>
);
}
say = () => {
const { value } = this.refs.greeting;
alert(value);
return value;
};
};
ReactDOM.render(<Speak />, document.getElementById('App'));

Resources