ReactJS and Helper File

Hey all, so I am making a tax calculator and need some help, I know I can add it all to the App.js file, but I want to keep the else if method on a different page.

So I have the App.js file, from create-react-app as per below

/* eslint-disable no-unused-vars */
import React, {Component} from 'react';
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import { InputGroup, InputGroupAddon, Input, Button } from 'reactstrap';
import {taxTable} from './tax'

class App extends Component {
  
  constructor(props) {
  super(props)
  this.state = {taxEarning: ''}
  }

  taxEarning = '';

  handleInput = event => {
    this.setState({taxEarning: event.target.value})
    let taxEarning = Math.floor(this.state.taxEarning) * 12
    console.log(`Taxable earning is: ${taxEarning}`)
  }

  render() {
  return (
    
    <div className="App container">
      <link
        rel="stylesheet"
        href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
        integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
        crossOrigin="anonymous"
      />
      <h1 className="jumbotron jumbotron-fluid">Welcome to Tax Calc</h1>
      <h3 className="alert alert-secondary" role="alert">Use the below form to calculate your monthly tax payable on your salary</h3>
      <p className="instructions">Please enter your monthly salary into the form below</p>
      <br />
      <br />
      <InputGroup>
        <InputGroupAddon addonType="prepend">R</InputGroupAddon>
        <Input
          placeholder="Amount"
          type="number"
          value={this.state.taxEarning}
          onChange={this.handleInput}
        />
        <InputGroupAddon addonType="append">.00</InputGroupAddon>
      </InputGroup>
      <br />
      <Button
        color="primary"
        onClick={this.handleInput}
        value={this.state.taxEarning}
        >Submit</Button>
      <br />
      <br />
      <p className="instructions">Tax payable is: R{}</p>
      
    </div>
  )};
}

export default App;

and I have imported the tax else if table into the App.js file, which looks like this:

/* eslint-disable no-undef */

function taxTable(taxEarning) {
    taxableIncome = 0
    if (taxEarning <= 195850) {
        taxableIncome = Math.floor(taxEarning * 0.18)
    } else if (taxEarning >= 195851 && taxEarning <= 305850) {
        taxableIncome = Math.floor(taxEarning * 0.26 - 35253)
    } else if (taxEarning >= 305851 && taxEarning <= 423300) {
        taxableIncome = Math.floor(taxEarning * 0.31 - 63853)
    } else if (taxEarning >= 423301 && taxEarning <= 555600) {
        taxableIncome = Math.floor(taxEarning * 0.36 - 100263)
    } else if (taxEarning >= 555601 && taxEarning <= 708310) {
        taxableIncome = Math.floor(taxEarning * 0.39 - 147891)
    } else if (taxEarning >= 708311 && taxEarning <= 1500000) {
        taxableIncome = Math.floor(taxEarning * 0.41 - 207448)
    } else if (taxEarning >= 1500001) {
        taxableIncome = Math.floor(taxEarning * 0.45 - 532041)
    }

    return ((Math.floor(taxEarning) - taxableIncome)/12).toFixed(2)
}

module.exports = taxTable

Though now, I want to take the user input and have it check the taxTable() with the taxEarning for the appropriate method and run that method and then return the output as per the module.

Can someone help me with this please :slight_smile:

Just run the function where it’s needed? You’ve written a function that does what you want it to do, apply it to the user input.

@DanCouper thanks, but thats where I get stuck, how do I apply it to the userInput to run it?

Maybe if it helps though, here is the sandbox link https://codesandbox.io/s/tax-calc-south-africa-2019-di3j2

You have imported the function taxTable, so in the line where you render “Tax payable is: …”, you just need to call the taxTable function with the taxEarning property of state as the argument.

1 Like

If the function takes a tax earning and runs the calculation, then something like

If I’m understanding what you’re trying to do correctly, then state like:

state = {
  taxEarning: 0,
  taxableIncome: 0
};

And handleinput like

  handleInput = event => {
    const taxEarning = Math.floor(this.state.taxEarning) * 12;
    this.setState({
      taxEarning,
      taxableIncome: taxTable(taxEarning)
    });
    console.log(`Taxable earning is: ${taxEarning}`)
  }

Then you can use this.state.taxableIncome once it’s been calculated. I’m not sure I’m applying the calculations in the correct place, you’d need to clarify that

Hi Randell, so I just pass it in here

Tax payable is: R{taxTable}

Or how would I pass it in there?

Do you know how to call a function and pass an argument to it?

Meaning in JS such as

function sayHello(name) {
console.log(sayHello)
}

as per the above?

or as

function sayHello(name) {
console.log(sayHello)
}
sayHello('YourName')

The above calls the function named sayHello and passes ‘YourName’ as its argument.

@DanCouper so I would need to append my constructor?

Ah okay yeah I follow yes @RandellDawson

I have a question. Is the purpose of the taxTable function to calculate the net monthly salary after taxes are taken out?

Yes that is correct yes, after taxes have been deducted

Then I have several suggestions:

Change the function name to something more meaningful (what the function does) like: calcMonthlyNetIncome.

Also I would use monthlySalary as the parameter name.

Instead of creating an extra state property, I would first rename your existing state property from taxEarning to monthlySalary which is really the value the user enters.

Then, you would would calculate the annual salary from the monthlySalary passed to the function and return the final monthly net income.

Your function would simplify to the following and be much more readable to anyone reviewing the code:

function calcMonthyNetIncome(monthlySalary) {
  const annualSalary = monthlySalary * 12
  let taxAmount = 0
  if (annualSalary <= 195850) {
    taxAmount = annualSalary * 0.18
  } else if (annualSalary <= 305850) {
    taxAmount = annualSalary * 0.26 - 35253
  } else if (annualSalary <= 423300) {
    taxAmount = annualSalary * 0.31 - 63853
  } else if (annualSalary <= 555600) {
    taxAmount = annualSalary * 0.36 - 100263
  } else if (annualSalary <= 708310) {
    taxAmount = annualSalary * 0.39 - 147891
  } else if (annualSalary <= 1500000) {
    taxAmount = annualSalary * 0.41 - 207448
  } else {
    taxAmount = annualSalary * 0.45 - 532041
  }
  return ((annualSalary - taxAmount) / 12).toFixed(2)
}

export default calcMonthyNetIncome

I also removed the Math.floors as the calculation will be more accurate.

I asked the question, because your form instructions say something different.

Use the below form to calculate your monthly tax payable on your salary

The above instructions indicate the form will calculate the monthly tax owed/payable and not the net income.

Ah okay I see yes, I removed the Math.floors now as well. The only reason why my function is called taxTable is due to the way we use it here, its made available and we all refer to it as tax table thus naming my function as such.

Use the below form to calculate your monthly tax payable on your salary

Yes, I need to amend the form and change some of it yes

When I see a function named taxTable, my first assumption is that it creates some kind of table (html) or a two-dimensional array. Function names should describe what they do/return. Variable names should describe the data contained in them. In the long run, it makes the code much more readable when you go back at some point to review the code and makes it easier for someone new to the code to quickly understand the intent of the code.

True yes, I follow what you mean by it, for instance if this was giving to someone outside my country, it’ll not make sens to them the way my function is called but the “calcMonthyNetIncome” would make sense. And this now also makes sense to me.