I am currently attempting to create a button which is red with the text "Yes" that when you click on it the button changes to a green color with the text "Confirm?" before the final stage in which an action takes place. Where I am currently at is defining buttonColor
as a state which changes on the click of the button; the initial color should be #FD8F83
and the final color after the click should be #A4D87C
. However, I am currently getting the error "TypeError: Cannot read property 'state' of undefined" pointing to the style={{backgroundColor: this.state.buttonColor}}
line whenever the code is compiled on the webpage.
Defining initial state and behavior on click:
getInitialState: function() {
return {
buttonColor: "#FD8F83"
};
},
handleClick(color) {
this.setState({
buttonColor: color
});
}
Code inside table in render():
<td>
<button
className="removeButton"
style={{backgroundColor: this.state.buttonColor}}
onClick={function(){this.handleClick("#A4D87C")}}>
Yes
</button>
</td>
Does anyone have any ideas why this is? I am brand new to React so I apologize if it's obvious. I also learned React using createClass so I've been trying to piece together how to make this work with the new create-react-class
package. Any advice is greatly appreciated!
React: ^16.2.0
Chrome: Version 63.0.3239.132 (Official Build) (64-bit)
Please provide the full code. (Otherwise it's hard to tell)
Hi @gaearon - here it is:
import React from 'react';
import {
Table
} from 'react-bootstrap';
var createReactClass = require('create-react-class');
var Customers = createReactClass({
getInitialState: function() {
return {
buttonColor: "#FD8F83"
};
},
handleClick(color) {
console.log("Button Color (state):", this.state.buttonColor);
this.setState({buttonColor: color});
},
render() {
return (
<Table striped bordered condensed hover>
<thead>
<tr>
<th>#</th>
<th>Customer Name</th>
<th>Username</th>
<th>Addl Username</th>
<th>Remove?</th>
</tr>
</thead>
<tbody>
{this.props.customers.map(function(customer, index) {
return (
<tr>
<td>{index + 1}</td>
<td>{customer.name}</td>
<td>{customer.fb_un}</td>
<td>{customer.em_un}</td>
<td>
<button
className="removeButton"
style={{backgroundColor: this.state.buttonColor}}
onClick={function(){this.handleClick("#A4D87C")}}>
Yes
</button>
</td>
</tr>
);
})}
</tbody>
</Table>
);
}
});
export default Customers;
@dallashuggins replace
this.props.customers.map(function(customer, index) {
with
this.props.customers.map((customer, index) => {
and that should fix it. The function
keyword switches the context of this
to be whatever object the function is bound to, in this case it's undefined. Arrow functions were added to JavaScript because of this behavior since they do not change the context of this
.
Also for future reference this is an issue thats better for some place like Stack Overflow, these threads are for tracking bugs.
The problem is:
onClick={function(){this.handleClick("#A4D87C")}}
In JS this
does not get preserved this way.
If you want to keep this
value from the render method you can use an arrow function:
onClick={() => {this.handleClick("#A4D87C")}}
Hope this helps!
Oh, and the above answer is also right (I missed that). Use arrows in both cases.
That worked! Thank you both so much!
not update state value,Please help
this.setState({ entityArray: resultEntities }, () => {
console.log(this.state.entityArray, 'entityArray');
});
you are not binding tour function , try to bind in constructor like :
constructor(props) {
super();
// binsings
this.myFunction = this.myFunction.bind(this)
}
binding in render will create a function in each render , and that will cause a small performance issue, so its best practice to bind in class constructor instead
gh
Hi @gaearon - here it is not working i tried
import React from 'react'; import { Table } from 'react-bootstrap'; var createReactClass = require('create-react-class'); var Customers = createReactClass({ getInitialState: function() { return { buttonColor: "#FD8F83" }; }, handleClick(color) { console.log("Button Color (state):", this.state.buttonColor); this.setState({buttonColor: color}); }, render() { return ( <Table striped bordered condensed hover> <thead> <tr> <th>#</th> <th>Customer Name</th> <th>Username</th> <th>Addl Username</th> <th>Remove?</th> </tr> </thead> <tbody> {this.props.customers.map(function(customer, index) { return ( <tr> <td>{index + 1}</td> <td>{customer.name}</td> <td>{customer.fb_un}</td> <td>{customer.em_un}</td> <td> <button className="removeButton" style={{backgroundColor: this.state.buttonColor}} onClick={function(){this.handleClick("#A4D87C")}}> Yes </button> </td> </tr> ); })} </tbody> </Table> ); } }); export default Customers;
const suppliers = this.state.bgpValidationData.map(function (data, idx) {
const details = '';
{ console.log(JSON.stringify(this)) }
return
{console.log(JSON.stringify(data))}
<Container className="noP col-sm-6" maxWidth="false"><a target="_blank" href={data.REQUEST.validationURL + '?url=specials:${' + data.REQUEST.CID + '}'} >{data.REQUEST.CID} </a></Container>
<Container className="noP col-sm-2" maxWidth="xs"> <FormLabel >{data.REQUEST.EVENT}</FormLabel></Container>
<Container className="noP col-sm-2" maxWidth="xs"> <FormLabel > {data.REQUEST.CKT_TYPE} </FormLabel></Container>
<Container className="noP col-sm-2" maxWidth="xs"> <FormLabel > {data.REQUEST.CKT_LAYER}</FormLabel></Container>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<Typography>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex,
sit amet blandit leo lobortis eget.
</Typography>
</ExpansionPanelDetails>
</ExpansionPanel>
})
return (
<div>{suppliers}</div>
);
Most helpful comment
@dallashuggins replace
this.props.customers.map(function(customer, index) {
with
this.props.customers.map((customer, index) => {
and that should fix it. The
function
keyword switches the context ofthis
to be whatever object the function is bound to, in this case it's undefined. Arrow functions were added to JavaScript because of this behavior since they do not change the context ofthis
.Also for future reference this is an issue thats better for some place like Stack Overflow, these threads are for tracking bugs.