6
\$\begingroup\$

This is just a very simple form that tells you the liquidity ratio, daily cost of running, and days cash on hand of a company, given their current assets, current liabilities, and total expense of the year.

The output gives you a very simplistic of how a company might be doing financially. The required input numbers can usually be found from a company's annual report or financial report if you have access to it.

I had been working for public organisations that publishes their annual financial report and had been doing these figures by hand to help myself to understand the financial state of the company. It merely helps myself as I don't have the financial background to really understand a financial report an accountant might.

I have written this form to practice using reactjs, as I am learning reactjs for the first time.

The codebase is relatively simple, all of the logic are stored just one file App.js:

import React, { useState, useEffect } from "react";
import "./styles.css";

const DefaultInstructionText = () => (
  <p>The result will be displayed here once all the fields are filled out.</p>
);

const Result = ({ liquidityRatio, dailyCost, daysCashOnHand }) => {
  const format = (num, roundFunc) => {
    if (num >= 1.0) {
      return parseFloat(roundFunc(num * 100) / 100).toFixed(2);
    } else {
      return num;
    }
  };
  return (
    <>
      <p>Liquidity ratio: {format(liquidityRatio, Math.floor)}</p>
      <p>Daily cost of running: {format(dailyCost, Math.ceil)}</p>
      <p>Days cash on hand: {format(daysCashOnHand, Math.floor)}</p>
    </>
  );
};

const NumberField = ({ label, value, changeHandler }) => {
  return (
    <label>
      {label}
      <br />
      <input
        type="number"
        required
        min={1}
        step="any"
        value={value}
        onChange={changeHandler}
      />
    </label>
  );
};

export default function App() {
  const [currentAsset, setCurrentAsset] = useState("");
  const [currentLiability, setCurrentLiability] = useState("");
  const [totalExpense, setTotalExpense] = useState("");
  const [showResult, setShowResult] = useState(false);
  const [liquidityRatio, setLiquidityRatio] = useState(null);
  const [dailyCost, setDailyCost] = useState(null);
  const [daysCashOnHand, setDaysCashOnHand] = useState(null);
  const validateNumber = num => {
    if (isNaN(num) || "" === num.trim() || num < 0) {
      return false;
    } else {
      return true;
    }
  };
  useEffect(() => {
    let newShowResult;
    if (
      validateNumber(currentAsset) &&
      validateNumber(currentLiability) &&
      validateNumber(totalExpense)
    ) {
      newShowResult = true;
    } else {
      newShowResult = false;
    }
    // New result need to be computed
    if (newShowResult) {
      /**
       * Liquidity ratio: Total current (quick) assets / total current liabilities (rounded down) (>= 1)
       * Daily cost of running: Total expenses / 365 (rounded up)
       * Days cash on hand: Total current asset / daily cost (rounded down) (>=90 days)
       */
      let newDailyCost = totalExpense / 365.0;
      setLiquidityRatio(currentAsset / currentLiability);
      setDailyCost(newDailyCost);
      setDaysCashOnHand(currentAsset / newDailyCost);
    }
    // Finally update showResult state
    setShowResult(newShowResult);
  }, [currentAsset, currentLiability, totalExpense]);
  return (
    <div className="App">
      <NumberField
        label="Current assets"
        value={currentAsset}
        changeHandler={e => {
          setCurrentAsset(e.target.value);
        }}
      />
      <NumberField
        label="Current liabilities"
        value={currentLiability}
        changeHandler={e => {
          setCurrentLiability(e.target.value);
        }}
      />
      <NumberField
        label="Total expenses"
        value={totalExpense}
        changeHandler={e => {
          setTotalExpense(e.target.value);
        }}
      />
      <hr />
      {showResult ? (
        <Result
          liquidityRatio={liquidityRatio}
          dailyCost={dailyCost}
          daysCashOnHand={daysCashOnHand}
        />
      ) : (
        <DefaultInstructionText />
      )}
    </div>
  );
}

The entire working codebase is on code sandbox if you like to read it there instead. You can actually see and test out the web form too: https://codesandbox.io/s/gracious-aryabhata-2bjmk

I am trying to stick with functional components and hooks as they seem to be the standard going forward with reactjs. I like to learn reactjs properly so please let me know if this is not the right way of doing things and anything that can be done better. Thank you! :)

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

You don't need to use useEffect and result states: liquidityRatio, dailyCost. Just edit like this

enter image description here

When you change your inputs, the render will be called and excecute from top to bottom. And result variables will be computed again.

Notes: That just basic answer for beginner in React.

\$\endgroup\$
4
  • \$\begingroup\$ Ah sure, it does work without useEffect. So when would be a good use case for useEffect? \$\endgroup\$
    – sunnz
    Commented Jul 3, 2020 at 14:41
  • 1
    \$\begingroup\$ Basically when you want to call api. Hmm... If you learn React in the rightway you will know when you use it! \$\endgroup\$ Commented Jul 3, 2020 at 16:24
  • 1
    \$\begingroup\$ We generally prefer code to be embedded in the question or answer rather than using an image. In a question the image of the code will get the question closed. \$\endgroup\$
    – pacmaninbw
    Commented Jul 4, 2020 at 15:53
  • \$\begingroup\$ Don't close the question please! \$\endgroup\$
    – sunnz
    Commented Jul 5, 2020 at 14:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.