want to execute disNone() function inside saveInfo() function when click on button - javascript

I want to execute disNone() inside saveInfo() when the button is clicked:
Error:TypeError: Cannot read property 'disNone' of undefined
import React, { Component } from 'react';
class Login extends Component {
constructor(props){
super(props);
this.state = {
dispNone:"dispNone",
message:"dispNone"
};
this.disNone = this.disNone.bind(this);
};
disNone(){
this.setState({
dispNone: "dispNone",
message:"dispBlock"
});
}
saveInfo(){
this.disNone();
}
render() {
return (
<div>
// other code
<button onClick={this.saveInfo}>Sign up</button>
</div>
);
}
}
export default Login;

In the constructor, besides this.disNone = this.disNone.bind(this), you also need to put
this.saveInfo = this.saveInfo.bind(this);
the error is because safeInfo does not know what this means, which gives you the error that disNone is undefined
EDIT: We do this in the constructor because we only need to bind the function once. Alternatively you could write it in the render function as well, but that means everytime the render function executes, you rebind the the function which is kind of a waste.
A third alternative is to use the () => this.saveInfo() inside the render function, this does not require any kind of binding anywhere, but again, this function has to be "created" every time the render function runs.

add
this.saveInfo = this.saveInfo.bind(this);
in your constructor.
SaveInfo method is not having access to this.

Related

Passing a parameter to an event handler in the parent class from a child class ReactJS

I am trying to pass a parameter to an event handler in a parent class, but am having some difficulty. I have done a good amount of research and am close to answer, but something's not quite working. Below I will give a basic hypothetical example of what I would like to do that doesn't work.
class Parent extends React.Component {
constructor(props){
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(i){
return event => console.log(i);
}
render(){
return <Child onClick={this.handleClick}></button>;
}
}
class Child extends React.Component {
render() {
const myVar = 2;
return <button onClick={this.props.onClick(myVar)}></button>;
}
}
I know the onClick prop that is passed to the Child is not a function, so I am unable to pass parameters directly to it. What is the best way to go about doing this? Thanks for you help!
Make the following update to your code
class Child extends React.Component{
render(){
const var = 2;
return <button onClick={ () => {this.props.onClick(var)} }</button>;
}
}
Furthermore, you should refactor the following method used by parent as so. You are passing e needlessly.
handleClick(i){
console.log(i);
}
The onClick on your child component was immediately invoked instead of waiting for the onClick event to fire.
You can't do
handleClick(i){
return (e => {console.log(i)});
}
instead, try
handleClick(i){
console.log(i)
}
and move the event handling to where it is being called. So instead of
<button onClick={this.props.onClick(var)}</button>
You want to try
<button onClick={e => this.props.onClick(var)}</button>

Function in react does not work as expected

I am trying to write a function that handles a button click.
I want things to happen:
The function gets a string and changes the state named "chosenGenre" to the given string.
When a certain button is clicked, it calls the function and returns a string.
The string/state "chosenGenre" is saved so I can use it later in another component.
This is what I have wrote but I think the way I deliver the string after the button is clicked isn't right.
import React, { Component } from 'react';
import Genre from './Genre';
import './GenreSelectPage.css';
import Blues from '../Blues.png';
import Classical from '../Classical.png';
import Country from '../Country.png';
export default class GenreSelectPage extends Component{
state = {
chosenGenre: ""
}
handleClick = (genreName) => {
this.setState({chosenGenre: genreName});
}
render(){
return(
<div className = "GenreSelectPage">
<h3>Select your desired Kollab Room Genre</h3>
<Genre genrePicture= {Blues} genreClicked = {this.handleClick("blues")}/>
<Genre genrePicture= {Classical} genreClicked = {this.handleClick("Classical")}/>
<Genre genrePicture= {Country} genreClicked = {this.handleClick("Country")}/>
)
}
}
What should I change in order to call the function in the right way and keep the result?
the problem is this.handleClick("blues") is executed during render, it returns undefined, similar to genreClicked={undefined}, with a side effect to schedule 3 asynchronous setStates...
you can use a factory function that returns an event handler function with access to a closure variable:
makeHandleClick = (genreName) => (event) => {
this.setState({ chosenGenre: genreName });
// console.assert(this.state.chosenGenre); // FYI: not possible, setState is async
}
render() {
...<Genre genrePicture={Blues} genreClicked={this.makeHandleClick("blues")} />

Binding this on method receiving parameters

I have an event handler which calls a fat arrow function to run a method.
import React, { Component } from 'react';
class App extends Component {
sayHi = msg => {
console.log(msg);
};
render() {
return (
<div>
<button onClick={() => this.sayHi('Hi')}>Console Hi!</button>
</div>
);
}
}
export default App;
I´m learning about contexts and bind() and, I want to convert this example to bind this. My problem is with the parameter that I´m passing when the fat arrow function executes the method, aka, 'Hi'
Is there a way to keep something like this...
<button onClick={this.sayHi('Hi')}>Console Hi!</button>
I tried different ways without good results. Mostly, focused on
constructor(props) {
super(props);
this.sayHi = this.sayHi.bind(this);
}
sayHi = () => {
console.log(msg);
};
And yes... I don´t want to move the 'Hi' to the method or constructor.
I´m trying to learn and understand. I will appreciate any kind of help or orientation.
You are mixing things. There are two cases for your situation and you are trying to use them both.
Binding to this
When do you need you bind your function to this? If you are calling your function in callback like your button (one of the cases of course) and you need to use this in this function then you need to bind it. If you don't use this then there is no need to bind it either.
sayHi() {
console.log("hi");
};
render() {
return (
<div>
<button onClick={this.sayHi}>Console Hi!</button>
</div>
);
}
}
Here, you don't need to bind it, also you can use the function with its reference since there is no argument.
constructor(props) {
super(props);
this.state = {
name: "foo",
}
this.sayHi = this.sayHi.bind(this);
}
sayHi() {
console.log(this.state.name);
};
render() {
return (
<div>
<button onClick={this.sayHi}>Console Hi!</button>
</div>
);
}
}
Here you are using this in the function, so you need to bind it in the constructor or define it as an arrow function.
Your situation
Now, your situation: You are defining your function as an arrow one, no need to bind it anymore if you will use this there. But you are not using it, then no need to use an arrow function. Also, you need to pass an argument to it. So, you need to find a way to accomplish this.
The first method, use an arrow function for onClick. Since if you don't use a callback here you can't use click.
sayHi(msg) {
console.log(msg);
};
render() {
return (
<div>
<button onClick={() => this.sayHi("hi")}>Console Hi!</button>
</div>
);
}
}
If you use like this.sayHi("hi") then this function is invoked in the first render, not with a click.
You can use .bind here as a second method also.
sayHi(msg) {
console.log(msg);
};
render() {
return (
<div>
<button onClick={this.sayHi.bind(null,"hi")}>Console Hi!</button>
</div>
);
}
}
See, we use bind but did not use this since we don't need it. We are not using this in our sayHi function.

ReactJS - Can't get function to load values from separate file after refactoring

After attempting to factor out functions within my App class in React into separate files, I am dealing with a whirlwind of import/export issues and was wondering if I could get some advice:
First, is factoring out functions from classes within other files/classes a logical thing to do?
Second, this is a specific problem that I'm having:
Expected Behavior: The function MainTable.tableGen() should return a value which App's render() can process.
Actual Behavior: Stepping through the debugger shows that tableGen() is not being fired, but it is recognized. In other words, it is not running the function and returning the value but returning the function as it's printed.
Main.js:
import MainTable from './app/components/input_table/maintable';
export default class App extends React.Component {
constructor(props){
this.MainTable = this.MainTable.bind(this);
}
MainTable(){
MainTable.tableGen(); //Call the function that's in the external file here
}
render(){
return (
<div>
<table>
<tbody onLoad = {this.broadcast()}>
{this.MainTable} //The MainTable.tableGen() function populates the table using a series of loops
</tbody>
</table>
<ButtonMenu onRow = {this.onRowButton} onCol = {this.onColumnButton} undo ={this.onUndoAction} redo = {this.onRedoAction} reset = {this.onResetAction} />
</div>
);
}
}
maintable.js:
class baseTable extends React.Component{
constructor(props){
//properties
super(props);
}
tableGen(){
... function code here...
}
const MainTable = new baseTable;
export default MainTable;
Make sure your tableGen() returns JSX, without quote.
return <h3>Hello World</h3>;
Then, your MainTable function should have return keyword:
MainTable() {
return MainTable.tableGen();
}
And, invoke the function when referencing it in JSX:
{this.MainTable()}

React binding this to a class method

So i'm reading a book on React which said I have to bind my methods like
this.onClickMe = this.onClickMe.bind(this);
but it looks to work just fine without using the above code
class ExplainBindingsComponent extends Component {
onClickMe() {
console.log(this);
}
render() {
return (
<button
onClick={ () => { this.onClickMe() } }
type="button"
>
Click Me
</button>
);
}
}
but it's saying I should do something like this,
class ExplainBindingsComponent extends Component {
constructor() {
super();
this.onClickMe = this.onClickMe.bind(this);
}
onClickMe() {
console.log(this);
}
render() {
return (
<button
onClick={this.onClickMe}
type="button"
>
Click Me
</button>
);
}
}
is this.onClickMe = this.onClickMe.bind(this); still something I have to do? and if so what does it do vs my above example
There are multiple ways to bind your function to the lexical context of the React class,
one such method is to bind it in the constructor,
other method is to use class fields as arrow functions, and
the third way to bind in the render using .bind or arrow,
Each of these can be used, however its best to avoid binding in the render since a new function is returned on each render
Using class field as arrow function.
class ExplainBindingsComponent extends Component {
onClickMe = () => {
console.log(this);
}
render() {
return (
<button
onClick={ this.onClickMe }
type="button"
>
Click Me
</button>
);
}
}
Binding in render
onClick={() => this.onClickMe() }
or
onClick={this.onClick.bind(this)}
is this.onClickMe = this.onClickMe.bind(this); still something I have to do?
You don't have to do it if you use arrow functions that capture lexical this. But it is considered to be a best practice because it allows you to avoid function creation inside render.
render() {
return (
<button
/* creates new function on every render call*/
onClick={ () => { this.onClickMe() } }
type="button"
>
Click Me
</button>
);
}
vs
constructor() {
super();
// creates function once per component instance
this.onClickMe = this.onClickMe.bind(this);
}
In your case, you don't need to because you use arrow function where this is bound to a context in which arrow function is defined - in this case to your component.
this.onClickMe = this.onClickMe.bind(this)
it's necessary when you pass function without any binding so it might be invoked where this will point to another object.
For anyone who is following 'React Step by Step' link and got stuck because in the example Clock, they haven't written any bind and it has worked well, but on the next example Toggle, they started to use bind(this).
Well, you can see the function tick(){...} (Clock class) and handleClick (){...} (Toggle class) are similar, as they both use the word this inside. Well the difference between them is how they are called. In the first (Clock), it is called using arrow function (inside componentDidMount() method) and using it allows you to bind automatically the word this with the object. On the other hand, the second method is not using ()=>{}, and need to bind this with the object. So for this purpose the assignment this.handleClick = this.handleClick.bind(this); helps you.
There are 3 ways to bind this
While defining the state. Like this:
this.state = {
this.eventHandler = this.eventHandler.bind(this)
}
Change the normal function to arrow function. Like this:
eventHandler = () => {
console.log('event handler');
}
Pass arrow function directly into the props. Like this:
<input onClick={(e) => this.eventHandler(e) } />
Hope this could resolve your problem.
~RDaksh

Categories