However the this.props.NotesAll retrieving object from another component and it's showing object's to under render() method but when I'm trying to use that this.props.NotesAll on top of render on a function to working with those object, and i'm trying to check the value with console on functions it's just always say's undefined shit. So please help me ReactNinja's what actually is the wrong is going on here.
Here codes you can have a look on them
export default class EditNotes extends Component {
constructor(props) {
super(props);
this.state ={};
}
handleEdit() {
console.log(this + ' Clicked on That ');
}
//Here it's throwing error when I'm trying to click and console. the problem is here. i want this.props.NotesAll value here also to finding elements from objects
handleDelete(id) {
let Notes = this.props.NotesAll;
console.log(Notes)
}
render() {
let noteItems;
//this.props.NotesAll working fine here.
if (this.props.NotesAll) {
noteItems = this.props.NotesAll.map( Note => {
return(
<li key={Note.id}>{Note.body}
<button onClick={this.handleEdit.bind(Note.id)} className="btn btn-primary btn-sm">Edit</button>
<button onClick={this.handleDelete.bind(Note.id)} className="btn btn-danger btn-sm">Delete</button></li>
);
});
}
return(
<div className="col-md-4">
<h3 className="header-ttile">Current Notes:</h3>
<ul className="note-item-wrapper">
{noteItems}
</ul>
</div>
);
}
}
You define the binding in a wrong way, first parameter will be the context to which you want to bind.
Use this:
<button onClick={this.handleDelete.bind(this, Note.id)}
Syntax:
fun.bind(thisArg[, arg1[, arg2[, ...]]])
thisArg:
The value to be passed as the this parameter to the target function
when the bound function is called.
constructor(props) {
super(props);
this.state ={};
this.notes = props.notesAll;
this.handleDelete = this.handleDelete.bind(this);
}
And then try to access your this.notes inside your handeDelete function. I'm not sure because I'm not a react ninja neither, but I think it should work this way
Related
I'm working on breaking up a little react app into smaller components. Before separating code everything worked as planned. I now am trying to call a function onChange that calls a function and then that calls a function as a prop. I am binding the function like this this.updateInput = this.updateInput.bind(this); but I still cannot figure out what I am missing. I tried a recent post on here (React : Pass function to child component) but the error still remains. Any help is great.
Here is the code I am working with:
class Weather extends React.Component {
constructor(props) {
super(props);
this.state = {
city: '',
details: []
};
this.updateInputValue = this.updateInputValue.bind(this);
}
updateInputValue(e) {
this.setState({
city: e.target.value
});
console.log('hit')
}
render() {
return (
<div className={style.container + ' ' + style.bodyText}>
<WeatherForm
updateInput={this.updateInputValue}
/>
</div>
);
}
}
class WeatherForm extends React.Component {
constructor(props) {
super(props);
this.updateInput = this.updateInput.bind(this);
}
updateInput(e) {
this.props.updateInputValue(e);
}
render() {
return (
<div className={style.weatherForm}>
<form action='/' method='GET'>
<input ref='city' value={this.props.inputValue} onChange={e => this.updateInput(e)} type='text' placeholder='Search city' />
</form>
</div>
);
}
}
So when I type one character in the input, instead of the console logging hit, it says Uncaught TypeError: this.props.updateInputValue is not a function. What am I missing here?
It should be
<WeatherForm
updateInputValue={this.updateInputValue}
/>
Common related problem:
The same "is not a function" error can also be caused by mis-using the props, as shown in this question
Your child component only has the prop of updateInput as a method and you're calling this.props.updateInputValue() in child component. Try to call them the same names.
You're also calling this.props.inputValue in the child component when you're not passing inputValue into your child component as a props.
What I would do to simplify the code and possible avoid mistakes like this in the future is to directly call this.props.updateInputValue in onChange event like this:onChange={e => this.props.updateInputValue(e)}
You then save the work of binding another component method in constructor. It'll also make your unit testing easier but that's another discussion.
This question already has answers here:
React 0.13 class method undefined
(2 answers)
Uncaught ReferenceError: handleClick is not defined - React
(3 answers)
Closed 5 years ago.
Basic functionality.
Print a list DONE
Adding a button to each list DONE
Button call a particular function. NOW WORKING!!!
THANKS ALL OF YOU GUYS! -
30/10/2017 - I found solution. In the end of const renderItems, I just added a simple this and works. of course, I forgot in this sample to add this.handleClick = this.handleClick.bind(this); on constructor. So now, is working to me
I already did research about it, and the best solution that I found was here: But every time that I try to use this guide: https://reactjs.org/docs/handling-events.html
But I always get the error:
Uncaught TypeError: Cannot read property 'handleClick' of undefined
and I can't understand why. What I did (or doing) wrong?
import React, { Component } from 'react';
import axios from 'axios';
class myApp extends Component {
constructor(props) {
super(props);
this.state = {
repos: []
};
this.handleClick = this.handleClick.bind(this); // ADDED
}
componentDidMount() {
var $this = this;
var URL = JSON;
axios.get(URL).then(function(res) {
$this.setState({
repos: res.data
});
})
.catch(function(e) {
console.log("ERROR ", e);
});
}
handleClick() {
console.log('this is:', this);
}
render() {
const renderItems = this.state.repos.map(function(repo, i) {
return <li
key={i}>
<a onClick={(e) => this.handleClick(e)} >Click here!</a>
<span className='repoName'>
{repo.full_name}
</span>
<hr />
</li>
}, this); // just added THIS!
return (
<ul>
{renderItems}
</ul>
<section className='target'>
Target
</section>
);
}
}
export default myApp;
Your this inside of (e) => this.handleClick(e) is not class this. Just do it this way onClick={this.handleClick}.This way you will have click event inside this in handleClick function. If you want class this inside handleClick, than do it this.handleClick.bind(this)
You get an undefined error because you have a missing parameter e in your method definition. handleClick() without a parameter has a different identity than handleClick(e).
Bind handleClick in your constructor: this.handleClick = this.handleClick.bind(this);
Then change the onClick prop to onClick={this.handleClick}. Never use arrow functions inside the render function, this creates new identities of the function on every re-render which is bad practice and might cause performance issues as your application grows.
You can also use the experimental public class fields syntax, then you can define your click handler like so;
handleClick = (e) => {
// Stuff
}
Like this, you don't need to do any binding and you can just put this.handleClick in your onClick prop.
I am trying to set onClick function of dynamic generated elements. The function has to set state.
var root = document.getElementById("results_container");
var title = document.createElement('a');
title.setAttribute("id", 'title');
title.onclick = function () {
this.setState({
isOpen: !this.state.isOpen
});
}.bind(this)
I am getting the Uncaught TypeError: Cannot read property 'state' of undefined and I am assuming that onclick function is unable to reach this.state. Please help
You can use jQuery function on. It binds the action even in newly generated element.
$(document).on('click', '#test', function() {
// statement here
})
For your reference: jQuery .on()
Your this variable is undefined... If you are using react, you need to store the reference to the component instance (this) somewhere, and pass that to your bind function. This is probably a very poor way to do this, however. If you are using react, you likely want something more like this:
class Results extends Component {
constructor(props) {
super(props);
this.state = {
isOpen: false
};
}
render() {
return <div>
<a onClick={()=>this.setState({isOpen:!this.state.isOpen})}>
Title
</a>
{this.state.isOpen ? this.getOpenContent() : null}
</div>;
}
getOpenContent() {
return <div> ... </div>;
}
}
I have some problem with splice() method in my React.js app.
So, this is an example app. Deletion not works now. What's wrong here? Part of code:
class CardList extends React.Component {
static propTypes = {
students: React.PropTypes.array.isRequired
};
// ADD DELETE FUNCTION
deletePerson(person) {
this.props.students.splice(this.props.students.indexOf(person), 1)
this.setState()
}
render() {
let that = this
return <div id='list'>
{this.props.students.map((person) => {
return <Card
onClick={that.deletePerson.bind(null, person)}
name={person.name}>
</Card>
})}
</div>
}
}
class Card extends React.Component {
render() {
return <div className='card'>
<p>{this.props.name}</p>
{/* ADD DELETE BUTTON */}
<button onClick={this.props.onClick}>Delete</button>
</div>
}
}
http://codepen.io/azat-io/pen/Vaxyjv
Your problem is that when you call
onClick={that.deletePerson.bind(null, person)}
You bind this value to null. So inside of your deletePerson function this is null instead of actual component. You should change it to
onClick={that.deletePerson.bind(this, person)}
And everything would work as expected =)
Changing the bind value to this will definitely cause the call to this.setState() to work, thus triggering the re-render, however I strongly recommend against the approach you've taken.
Props are supposed to be immutable. Instead use internal state and replace with new values rather than mutate them. To do this, set the state of your component in the constructor by doing something like:
constructor(props) {
super(props)
this.state = {
students: ...this.props.students
}
}
And now when you need to delete a person:
deletePerson(person) {
// notice the use of slice vs splice
var newStudents = this.props.students.slice(this.props.students.indexOf(person), 1)
this.setState({ students: newStudents })
}
And finally use this.state.students in your render method instead.
The reasoning behind this is that props are passed directly from the parent container component so modifying them wouldn't really make sense. To make more sense of my own code, I tend to pass in the prop named initialStudents and set my state to students: ...initialStudents to ensure I make the distinction between my prop variable and my state variable.
I have a component that I have created:
class Create extends Component {
constructor(props) {
super(props);
}
render() {
var playlistDOM = this.renderPlaylists(this.props.playlists);
return (
<div>
{playlistDOM}
</div>
)
}
activatePlaylist(playlistId) {
debugger;
}
renderPlaylists(playlists) {
return playlists.map(playlist => {
return <div key={playlist.playlist_id} onClick={this.activatePlaylist(playlist.playlist_id)}>{playlist.playlist_name}</div>
});
}
}
function mapStateToProps(state) {
return {
playlists: state.playlists
}
}
export default connect(mapStateToProps)(Create);
When I render this page, activatePlaylist is called for each playlist in my map. If I bind activatePlaylist like:
activatePlaylist.bind(this, playlist.playlist_id)
I can also use an anonymous function:
onClick={() => this.activatePlaylist(playlist.playlist_id)}
then it works as expected. Why does this happen?
You need pass to onClick reference to function, when you do like this activatePlaylist( .. ) you call function and pass to onClick value that returned from activatePlaylist. You can use one of these three options:
1. using .bind
activatePlaylist.bind(this, playlist.playlist_id)
2. using arrow function
onClick={ () => this.activatePlaylist(playlist.playlist_id) }
3. or return function from activatePlaylist
activatePlaylist(playlistId) {
return function () {
// you code
}
}
I know this post is a few years old already, but just to reference the latest React tutorial/documentation about this common mistake (I made it too) from https://reactjs.org/tutorial/tutorial.html:
Note
To save typing and avoid the confusing behavior of this, we will use
the arrow function syntax for event handlers here and further below:
class Square extends React.Component {
render() {
return (
<button className="square" onClick={() => alert('click')}>
{this.props.value}
</button>
);
}
}
Notice how with onClick={() => alert('click')}, we’re passing a
function as the onClick prop. React will only call this function after
a click. Forgetting () => and writing onClick={alert('click')} is a
common mistake, and would fire the alert every time the component
re-renders.
This behaviour was documented when React announced the release of class based components.
https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html
Autobinding
React.createClass has a built-in magic feature that bound all methods to this automatically for you. This can be a little confusing for JavaScript developers that are not used to this feature in other classes, or it can be confusing when they move from React to other classes.
Therefore we decided not to have this built-in into React's class model. You can still explicitly prebind methods in your constructor if you want.
import React from 'react';
import { Page ,Navbar, Popup} from 'framework7-react';
class AssignmentDashboard extends React.Component {
constructor(props) {
super(props);
this.state = {
}
onSelectList=(ProjectId)=>{
return(
console.log(ProjectId,"projectid")
)
}
render() {
return (
<li key={index} onClick={()=> this.onSelectList(item.ProjectId)}></li>
)}
The way you passing the method this.activatePlaylist(playlist.playlist_id), will call the method immediately. You should pass the reference of the method to the onClick event. Follow one of the below-mentioned implementation to resolve your problem.
1.
onClick={this.activatePlaylist.bind(this,playlist.playlist_id)}
Here bind property is used to create a reference of the this.activatePlaylist method by passing this context and argument playlist.playlist_id
2.
onClick={ (event) => { this.activatePlaylist.(playlist.playlist_id)}}
This will attach a function to the onClick event which will get triggered on user click action only. When this code exectues the this.activatePlaylist method will be called.