Lifting state up - "Cannot POST / " Error

Hello friends,

Currently following @zsolt-nagy React tutorial, I’ve stumbled upon this error while clicking the “refresh” button when implementing the click handler.

Screenshot 2021-05-14 at 10.57.00

Everything seems in place. In the Coin.jsx file, the button has its “onClick” and is binded in the constructor:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const Td = styled.td`
    border: 1px solid #cccccc;
    width: 25vh;   
`;

export default class Coin extends Component {

    constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick(event) {
        //Prevent the default action of refresh first
        event.preventDefault();
        this.props.handleRefresh(this.props.ticker);

    }

    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.props.handleClick}>Refresh</button>
                        </form>
                    </Td>
            </tr>
        );
    }
}

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

Now in the CoinList.jsx file, the handleRefresh call is indeed submitted to the parent:

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.4rem;
`;

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>
        )
    }
}

And finally, in App.js:

import React from 'react';
import AccountBalance from './components/AccountBalance/AccountBalance'
import { v4 as uuidv4 } from 'uuid';
import CoinList from './components/CoinList/CoinList';
import Header from './components/Header/Header'
import styled from 'styled-components';

const Div = styled.div`
  text-align: center;
  background-color: rgb(120, 120, 173);
  color: #cccccc;
`;

class App extends React.Component {
  constructor (props){
    super(props);
    this.handleRefresh = this.handleRefresh.bind(this);
    this.state = {
      balance: 10000,
      coinData:[
        {
          key: uuidv4(),
          name: 'Bitcoin',
          ticker: 'BTC',
          price: 9999.9
        },
        {
          key: uuidv4(),
          name: 'Ethereum',
          ticker: 'ETH',
          price: 1000
        },
        {
          key: uuidv4(),
          name: 'Ripple',
          ticker: 'XRP',
          price: 0.2
        },
        {
          key: uuidv4(),
          name: 'Tether',
          ticker: 'USDT',
          price: 1
        },
        {
          key: uuidv4(),
          name: 'Cardano',
          ticker: 'ADA',
          price: 2
        }
      ],
    };
  };

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

  render() {
    return (
      <Div className="App">
        <Header />
        <AccountBalance amount={this.state.balance} />
        <CoinList coinData={this.state.coinData} handleRefresh={this.handleRefresh} />
      </Div>
    );
  }

};

export default App;

What do you guys see I am missing?

Thank you so much for your help!

Found it, I’ve left ‘props’ in this expression in Coin.jsx:

<button onClick={this.props.handleClick}>Refresh</button>

Should be:

<button onClick={this.handleClick}>Refresh</button>

The button was trying to call an event passed as props, which doesn’t exist…

Thanks!

2 Likes