So I started converting my application from ES2015 to ES6 which uses React. You're binding your child's login function but not your parent's. – ivarni Sep 15, 2016 at 5:24 If you are using ES6 then manual binding is not required but if you want you can. You can use arrow functions if you want to stay away with scope related issues and manual function/object bindings.
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count : 1
};
this.delta = this.delta.bind(this);
}
delta() {
this.setState({
count : this.state.count++
});
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.delta}>+</button>
</div>
);
}
}
You can use arrow function to bind you functions. You need to bind you functions both in child as well as parent components.
Parent:
export default class Parent extends Component {
constructor(props) {
super(props);
this.state = {
code: ''
};
}
setCodeChange = (newCode) => {
this.setState({code: newCode});
}
login = () => {
if (this.state.code == "") {
// Some functionality
}
}
render() {
return (
<div>
<Child onCodeChange={this.setCodeChange} onLogin={this.login} />
</div>
);
}
}
Child
export default class Child extends Component {
constructor(props) {
super(props);
}
handleCodeChange = (e) => {
this.props.onCodeChange(e.target.value);
}
login = () => {
this.props.onLogin();
}
render() {
return (
<div>
<input name="code" onChange={this.handleCodeChange}/>
</div>
<button id="login" onClick={this.login}>
);
}
}
Child.propTypes = {
onCodeChange: React.PropTypes.func,
onLogin: React.PropTypes.func
};
You are not recommended to bind your functions directly in render. You are recommended to bind it in constructor always because if you do binding directly in render then whenever your component renders Webpack will create a new function/object in bundled file thus the Webpack bundle file size grows. For many reasons your component re-renders eg: doing setState but if you place it in constructor it gets called called only once.
The below implementation is not recommended
<Child onCodeChange={this.setCodeChange.bind(this)} onLogin={this.login.bind(this)} />
Do it in constructor always and use the ref wherever required
constructor(props){
super(props);
this.login = this.login.bind(this);
this.setCodeChange = this.setCodeChange.bind(this);
}
<Child onCodeChange={this.setCodeChange} onLogin={this.login} />
Cannot read property means the code was trying to read a property. 'map' is the property the code was trying to read There are a handful of built-in error types. MDN says TypeError “represents an error that occurs when a variable or parameter is not of a valid type.” (this part is, IMO, the least useful part of the error message) If you’re looking at the browser console instead, you’ll need to read the stack trace to figure out where the error was.
6 | return ( 7 | <div className="App"> 8 | <h1>List of Items</h1>> 9 | {items.map((item) => ( | ^ 10 | <div key={item.id}> 11 | {item.name} 12 | </div>
TypeError: Cannot read property 'map' of undefined
at App (App.js:9)
at renderWithHooks (react-dom.development.js:10021)
at mountIndeterminateComponent (react-dom.development.js:12143)
at beginWork (react-dom.development.js:12942)
at HTMLUnknownElement.callCallback (react-dom.development.js:2746)
at Object.invokeGuardedCallbackDev (react-dom.development.js:2770)
at invokeGuardedCallback (react-dom.development.js:2804)
at beginWork$1 (react-dom.development.js:16114)
at performUnitOfWork (react-dom.development.js:15339)
at workLoopSync (react-dom.development.js:15293)
at renderRootSync (react-dom.development.js:15268)
at performSyncWorkOnRoot (react-dom.development.js:15008)
at scheduleUpdateOnFiber (react-dom.development.js:14770)
at updateContainer (react-dom.development.js:17211)
at eval (react-dom.development.js:17610)
at unbatchedUpdates (react-dom.development.js:15104)
at legacyRenderSubtreeIntoContainer (react-dom.development.js:17609)
at Object.render (react-dom.development.js:17672)
at evaluate (index.js:7)
at z (eval.js:42)
at G.evaluate (transpiled-module.js:692)
at be.evaluateTranspiledModule (manager.js:286)
at be.evaluateModule (manager.js:257)
at compile.ts:717
at l (runtime.js:45)
at Generator._invoke (runtime.js:274)
at Generator.forEach.e.<computed> [as next] (runtime.js:97)
at t (asyncToGenerator.js:3)
at i (asyncToGenerator.js:25)
at App(App.js: 9)
import "./styles.css";
export default function App() {
let items;
return (
<div className="App">
<h1>List of Items</h1>
{items.map(item => (
<div key={item.id}>
{item.name}
</div>
))}
</div>
);
}
{
items.map(item => (
Uncaught TypeError: Cannot read property 'setState' of undefined Uncaught TypeError Cannot read property ... 69548/uncaught-typeerror-cannot-read-property-setstate-undefined I am getting the following error
even after binding delta in the constructor.
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count : 1
};
this.delta.bind(this);
}
delta() {
this.setState({
count : this.state.count++
});
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.delta}>+</button>
</div>
);
}
}
When using ES6 code in React always use arrow functions, because this context is automatically binded.
so use this:
(videos) => {
this.setState({
videos: videos
});
console.log(this.state.videos);
};
instead of:
function(videos) {
this.setState({
videos: videos
});
console.log(this.state.videos);
};
Error Cannot read property setState of... 78129/error-cannot-read-property-setstate-of-undefined In order to bind set this.delta = this.delta.bind(this) in the constructor: even after binding delta in the constructor.
I am getting the following error
Uncaught TypeError: Cannot read property 'setState' of undefined
even after binding delta in the constructor.
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count : 1
};
this.delta.bind(this);
}
delta() {
this.setState({
count : this.state.count++
});
}
render() {
return (
<div>
<h1>{this.state.count}</h1>
<button onClick={this.delta}>+</button>
</div>
);
}
}
This is due to this.delta not being bound to this.
constructor(props) {
super(props);
this.state = {
count: 1
};
this.delta = this.delta.bind(this);
}
when I try to lift the state from Counters to App and I save i see the following error in the dev tool: Uncaught TypeError: Cannot read properties of undefined (reading ‘map’) It looks like my properties from Counters component in the App class is empty (I have tried to log it in the console unsuccessfully). I tried to reverse the change and everything works fine. Strange. I tried your code and I’m not seeing any errors! It seems to work. I don’t import NavBar and App.css because I don’t have those, but otherwise I think it’s mostly the same. Here are the three files:
class App extends Component {
state = {
counters: [
{
id: 1,
value: 1
},
{
id: 2,
value: 0
},
{
id: 3,
value: 0
},
{
id: 4,
value: 1
},
],
};
handleDelete = (counterId) => {
// console.log("Delete button clicked", counterId);
const counters = this.state.counters.filter((c) => c.id !== counterId);
this.setState({
counters
});
};
handleReset = () => {
const counters = this.state.counters.map((c) => {
c.value = 0;
return c;
});
this.setState({
counters
});
render(){
return (
<React.Fragment>
<NavBar/>
<main className='container'>
<Counters
counters = {this.state.counters}
onReset = {this.handleReset}
onIncrement = {this.handleIncrement}
onDelete = {this.handleDelete}
/>
</main>
</React.Fragment>
class Counters extends Component {
render() {
return (
<div>
<button
onClick={this.props.onReset}
className="btn btn-primary btn-sm m-2"
>
Resets
</button>
{this.props.counters.map((counter) => (
<Counter
key={counter.id}
onDelete={this.props.onDelete}
counter={counter}
onIncrement={this.props.onIncrement}
/>
))}
</div>
);
If you are a React developer or are just learning to program in JavaScript, you might have run into this dreaded error while trying to read a property off of the this keyword: So you've diagnosed the problem. You need to make sure that your functions have access to the this context of your class component! To do this, you can use ES6 arrow functions. This guide will dive into how function scope works in JavaScript. You will learn why this error occurs and what you can do to fix it.
1TypeError: Cannot read property '<your property name>' of undefined
1class FishSpecies Extends React.Component {
2 constructor(props) {
3 super(props);
4 this.state = {
5 clickCount: 0
6 };
7 }
8
9 onFishClicked() {
10 this.setState(function(prevState, props) {
11 return { clickCount: prevState.clickCount + 1 };
12 });
13 }
14
15 render() {
16 return (
17 <ul>
18 {{ this.props.fish.map(function(fish) {
19 return <Fish name={fish.name} onClick={this.onFishClicked} />
20 })}}
21 </ul>
22 )
23 }
24}
1 TypeError: Cannot read property 'onFishClicked' of undefined