I am creating a component that contains of a Form with a Submit button. In the OnSubmit of the Form I call an arrow function. Inside this function I call the object "this" but I get the error message that it is undefined. However, if I just do a console.log(this) in the OnSubmit of the form instead of calling the arrow function, this is defined. Anyone knows how to solve this issue ? I am actually following a react/ethereum course and even though the code of the instructor works in his video, his code doesn't work when I use it.
import React, {Component} from 'react';
import { Button, Form, Input, Message } from 'semantic-ui-react'
class CampaignNew extends Component{
state = {
minimumContribution: "",
errorMessage: ""
}
onSubmit = async (event) => {
event.preventDefault();
this.setState({errorMessage: "test error"});
}
render(){
return (
<div>
<Form onSubmit={this.onSubmit} error={this.state.errorMessage}>
<Form.Field>
<label>Minimum contribution</label>
<Input
labelPosition="right"
value={this.state.minimumContribution}
onChange={event => this.setState({minimumContribution: event.target.value})}
style={{width: "250px"}} placeholder='0' />
</Form.Field>
<Button type='submit' primary>Create</Button>
</Form>
</div>
)
}
}
export default CampaignNew;
CodePudding user response:
That's related to how this value is defined in javaScript. You should know that "this" value is defined by who calls it in runtime.
In Class, "this" value is the same this value of its parent. In this code, "this" value is CampaignNew class object.
class CampaignNew extends Component{
onSubmit = async (event) => {
event.preventDefault();
this.setState({errorMessage: "test error"});
}
But "this" value is different in code below.
<Form onSubmit={this.onSubmit}
This is because Form element calls onSubmit which means this value in onSubmit is the same value of Form element's "this" and Form element doesn't have this value so this is why the value's undefined.
CodePudding user response:
Your code runs fine for me, but there is some missing information on how you are creating your component. It seems you may not be using Create-React-App. Your issue is with method binding in a class component.
The React documentation (https://reactjs.org/docs/handling-events.html) states:
You have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default. If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called.
This is not React-specific behavior; it is a part of how functions work in JavaScript. Generally, if you refer to a method without () after it, such as onClick={this.handleClick}, you should bind that method.
If calling bind annoys you, there are two ways you can get around this. If you are using the experimental public class fields syntax, you can use class fields to correctly bind callbacks:
class LoggingButton extends React.Component {
// This syntax ensures `this` is bound within handleClick.
// Warning: this is *experimental* syntax.
handleClick = () => { console.log('this is:', this); }
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
This syntax is enabled by default in Create React App.
Also the error prop of the Form component should be a boolean and the async word is not required in the code you provided.
