简体   繁体   中英

How do I pass a function as a property to a React component?

In an effort to figure out the problem I explain in my (unanswered) question "How do I update a react-bootstrap-table2 cell value after it's edited so a button component in a different column has it?" , I attempted to pass a function that returns the cell value into the button component:

class NominationQueueBootstrapTable extends Component {

...

  getInitialBid = (row) => {
    console.log('getInitialBid');
    return this.state.data.find(r => r.rank === row.rank).initialBid;
  }

  render() {
    const { auctionId } = this.props;
    const { teamId } = this.props;

    function buttonFormatter(cell, row) {
      return (
        <NominateButton
          row={ row }
          auctionId={ auctionId }
          teamId={ teamId }
          getInitialBid={ this.getInitialBid }
        />
      );
    }

...

My NominateButton component returns another button wrapper component that calls a mutator:

class NominateButton extends Component {
  render() {
    const { row } = this.props;
    const { auctionId } = this.props;
    const { teamId } = this.props;
    const playerId = parseInt(this.props.row.player.id, 10);

    return (
      <Query
        query={TEAM_NOMINATIONS_OPEN_QUERY}
        variables={{ team_id: teamId }}>
        {({ data, loading, error, subscribeToMore }) => {
          if (loading) return <Loading />;
          if (error) return <Error error={error} />;
          return (
            <NominateButtonMutator
              auctionId={ auctionId }
              teamId={ teamId }
              playerId={ playerId }
              row={ row }
              nominationsOpen={ data.team.nominationsOpen }
              subscribeToNominationsOpenChanges={ subscribeToMore }
              getInitialBid={ this.props.getInitialBid }
            />
          );
        }}
      </Query>
    );
  }
}

And because I need to invoke the mutator when the button is pressed, my onClick function first calls the getInitialBid function passed in as a property, and then invokes the mutator:

class NominateButtonMutator extends Component {

...

  handleButtonPressed = (submitBid) => {
    this.setState({bidAmount: this.props.getInitialBid(this.props.row)});
    submitBid();
  };

  render() {
    const { auctionId } = this.props;
    const { teamId } = this.props;
    const { playerId } = this.props;
    const { nominationsOpen } = this.props;

    return (
      <Mutation
        mutation={SUBMIT_BID_MUTATION}
        variables={{
          auction_id: auctionId,
          team_id: teamId,
          player_id: playerId,
          bid_amount: this.state.bidAmount
        }}
      >
        {(submitBid, { loading, error }) => (
          <div>
            <Error error={error} />
            <Button
              disabled={ loading || !nominationsOpen }
              onClick={() => this.handleButtonPressed(submitBid) }
              variant="outline-success">
              Nominate
            </Button>
          </div>
        )}
      </Mutation>
    );
  }
}

(The onClick= code was updated from azium 's comment.)

When I run this, I get:

"TypeError: this.props.getInitialBid is not a function"

在此处输入图像描述

Is this a workable strategy? Why isn't this.props.getInitialBid a function?

You are using the old function syntax, so this is not bound correctly.

change:

function buttonFormatter(cell, row) {
  return (
    <NominateButton
      row={ row }
      auctionId={ auctionId }
      teamId={ teamId }
      // scoped to your local function not your class
      getInitialBid={ this.getInitialBid } 
    />
  );
}

to

const buttonFormatter = (cell, row) => {
  return (
    <NominateButton
      row={ row }
      auctionId={ auctionId }
      teamId={ teamId }
      // this is scoped "lexically" aka to your class
      getInitialBid={ this.getInitialBid }
    />
  );
}

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