I only recently started coding in React and I'm in need of some assistance. I'm building a simple calculator and I'm trying to pass an event handler to a child component. In the flow of the app, the App component is the parent component. It houses a child "Button Panel" component, which in turn houses child "Button" components as follows:
import React from 'react';
import Display from './display';
import ButtonPanel from './button-panel';
import method from '../logic/calculate';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
total: null,
next: null,
operation: null,
};
this.handleClick = this.handleClick.bind(this);
}
handleClick(buttonName) {
// Updates this.state based on buttonName
}
render() {
const { total } = this.state;
return (
<div id="app">
<Display result={total} />
<ButtonPanel onClick={this.handleClick} />
</div>
);
}
}
export default App;
------------------------------------------------------------------------------------------------
import React from 'react';
import PropTypes from 'prop-types';
import Button from './button';
class ButtonPanel extends React.Component {
constructor(props) {
super(props);
this.passInfo = this.passInfo.bind(this);
}
passInfo(buttonName) {
const { handleClick } = this.props;
handleClick(buttonName);
}
render() {
return (
<div>
<div className="panel-row">
<Button name="AC" color="white" onClick={this.passInfo} />
<Button name="+/-" color="white" onClick={this.passInfo} />
<Button name="%" color="white" onClick={this.passInfo} />
<Button name="/" onClick={this.passInfo} />
</div>
<div className="panel-row">
<Button name="7" color="white" onClick={this.passInfo} />
<Button name="8" color="white" onClick={this.passInfo} />
<Button name="9" color="white" onClick={this.passInfo} />
<Button name="X" />
</div>
<div className="panel-row">
<Button name="4" color="white" onClick={this.passInfo} />
<Button name="5" color="white" onClick={this.passInfo} />
<Button name="6" color="white" onClick={this.passInfo} />
<Button name="-" onClick={this.passInfo} />
</div>
<div className="panel-row">
<Button name="1" color="white" onClick={this.passInfo} />
<Button name="2" color="white" onClick={this.passInfo} />
<Button name="3" color="white" onClick={this.passInfo} />
<Button name="+" />
</div>
<div className="panel-row">
<Button name="0" color="white" wide onClick={this.passInfo} />
<Button name="." color="white" onClick={this.passInfo} />
<Button name="=" onClick={this.passInfo} />
</div>
</div>
);
}
}
ButtonPanel.propTypes = {
handleClick: PropTypes.func.isRequired,
};
export default ButtonPanel;
------------------------------------------------------------------------------------------------
import React from 'react';
import PropTypes from 'prop-types';
class Button extends React.Component {
constructor(props) {
super(props);
this.namePass = this.namePass.bind(this);
}
namePass(e) {
const { name } = e.target;
const { handleClick } = this.props;
handleClick(name);
}
render() {
const { name, color, wide } = this.props;
const classes = color === 'white' && wide ? 'white wide' : color;
return (
<div
className={classes}
onClick={this.namePass}
onKeyPress={this.namePass}
role="button"
tabIndex="-1"
>
{name}
</div>
);
}
}
Button.propTypes = {
name: PropTypes.string.isRequired,
color: PropTypes.string,
wide: PropTypes.bool,
handleClick: PropTypes.func.isRequired,
};
Button.defaultProps = {
color: 'orange',
wide: false,
};
export default Button;
(please excuse the hard-coding, I'm trying to get everything working before refactoring).
At the moment though, I'm getting the following errors:
1) "Warning: Failed prop type: The prop handleClick is marked as required in ButtonPanel, but its value is undefined in ButtonPanel"
2) "Warning: Failed prop type: The prop handleClick is marked as required in Button, but its value is undefined in Button"
Any assistance in solving this would be greatly appreciated.
handleClickto the props validation, but you're passing the function inonClick. Just changing it tohandleClick={this.handleClick}would work.