× TypeError: this.props.handleRefresh is not a function in React

Viewed 34

I keep on getting the same error even after going through all the spelling errors and trying different solutions to similar issues.

handleRefresh() function defined in App.js.

It is supposed to find it like this:

App.js -> CoinList.jsx -> Coin.jsx

Error message is still the same even when I tried drop or add props

  19 | handleClick(event) {
  20 |    event.preventDefault();
  21 | 
> 22 |    this.props.handleRefresh(this.props.ticker);     
     | ^  23 |    
  24 |    // const randomPercentage = 0.995 + Math.random() * 0.01;
  25 |    // this.setState( function(oldState) {

Coin.jsx

import PropTypes from 'prop-types';
import styled from 'styled-components';

const Td = styled.td`
   border: 2px solid black;
   width: 20vh;
`

export default class Coin extends Component {
   constructor  (props) {
      super(props);
      // this.state = {
      //    price: this.props.price 
      // }
      this.handleClick = this.handleClick.bind(this);
   }
  
   handleClick(event) {
      event.preventDefault();

      this.props.handleRefresh(this.props.ticker);     
      
      // const randomPercentage = 0.995 + Math.random() * 0.01;
      // this.setState( function(oldState) {
      //    return {
      //       price: oldState.price * randomPercentage
      //    };
      // })
   }
     
   render() {
      return (
         <tr>
            <Td>{this.props.name}</Td>
            <Td>{this.props.ticker}</Td>
            <Td>${this.props.price}</Td>
            <Td>
               <form action="#" method="POST">
                  <button onClick={this.handleClick}>Refresh</button>
               </form>
      
            </Td>
         </tr>
      );
   }
}

Coin.propTypes = {
   name: PropTypes.string.isRequired,
   ticker: PropTypes.string.isRequired,
   price: PropTypes.number.isRequired 
} 

CoinList.jsx

import React, { Component } from 'react'
import Coin from '../Coin/Coin';
import styled from 'styled-components';

const Table = styled.table`
    margin: 50px auto 50px auto;
    display: inline-block;
    font-size: 1.5rem;
`
export default class CoinList extends Component {
  render() {
    return (
        <Table>
            <thead>
            <tr>
                <th>Name</th>
                <th>Ticker</th>
                <th>Price</th>
            </tr>
            </thead>
            <tbody>
            { 
                this.props.coinData.map(({name, ticker, price}) => 
                    <Coin key={ticker} 
                    handleRefresh={this.props.handleRefresh}
                    name={name} 
                    ticker={ticker} 
                    price={price} />
                )
            }
            </tbody>
        </Table>
    )
  }
}

App.js

import AccountBalance from './components/AccountBalance/AccountBalance';
import styled from 'styled-components';
import React from 'react'
import CoinList from './components/CoinList/CoinList';
import ExchangeHeader from './components/ExchangeHeader/ExchangeHeader';

const AppCss = styled.div`
  text-align: center;
  background-color: rgb(151, 69, 201);
  color: rgb(255, 255, 255);
`
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      balance: 20000,
      coinData: [
        {
          name: "Bitcoin", 
          ticker: "BTC",
          price: 29999.99
        },
        {
          name: "Ethereum", 
          ticker: "ETH",
          price: 1900
        },
        {
          name: "Dogecoin", 
          ticker: "DOGE",
          price: 0.003
        },
        {
          name: "Tether", 
          ticker: "USDT",
          price: 1.0
        },
        {
          name: "Solana", 
          ticker: "SOL",
          price: 50
        }

      ]
    }
    this.handleRefresh = this.handleRefresh(this);
  }

  handleRefresh(valueChangeTicker){
    const coin = this.state.coinData.find(({ticker}) => ticker === valueChangeTicker );
    console.log( coin );
  }

  render() {
    return (
      <AppCss>
        <ExchangeHeader />
        <AccountBalance amount={this.state.balance}/>
        <CoinList coinData={this.state.coinData} handleRefresh={this.handleRefresh}/>
      </AppCss>
    );
  }
  
}

export default App;

1 Answers

Try changing this.handleRefresh = this.handleRefresh(this); to this.handleRefresh = this.handleRefresh.bind(this)

Related