简体   繁体   中英

Implementing Event Handler in React

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.

Change handleClick in proptypes to onClick OR rename onClick to handleClick.

The warning is coming from Proptypes. It is expecting handleClick prop for both custom components but you are using onClick instead.

I would go with the latter as onClick is normally a default prop for many elements.

ButtonPanel.propTypes = {
  onClick: PropTypes.func.isRequired,
};

Button.propTypes = {
  onClick: PropTypes.func.isRequired,
  ...
};

OR

<ButtonPanel handleClick={this.handleClick} />
<Button handleClick={this.handleClick} ..... />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM