Search code examples
reactjsweb-deployment

React component taking some random values


These are my components. This is quicksort.js =>

import React from "react";
import "../CSS/Quicksort.css";
import Bar from "./Bar";

export default function Quicksort() {
  var arr = new Array(50);
  for (var i = 0; i < 50; ++i) {
    arr[i] = Math.floor(Math.random() * Math.floor(400));
  }

  console.log(arr);
  arr.sort(function (a, b) {
    return  a-b;
  });
  console.log(arr);
  const mp = arr.map((num, idx) => {
    return <Bar key={idx} height={num} />;
  });
  return (
    <>
      <div className="layout">{mp}</div>
    </>
  );
}

This is Bar.js =>

import { makeStyles } from '@material-ui/core/styles';
import React from 'react'
import '../CSS/Bar.css';

export default function Bar({height}) {
    const useStyles = makeStyles({
        bar:{
            fontSize:10,
            height:height,
            width:20,
            backgroundColor:"red",
            color:"white"
        }
    });
    const classes = useStyles();
    return (
        <>
            <div className={classes.bar} >
                {height}
            </div>
        </>
    )
}

and this is the picture of the output

enter image description here

Look at the element inspected the 4th element in the array and the rendered element. In the image it is that the 4th element I passed from the randomly generated array which is 21 but the height of the element rendered is 23. Please help me with this. Thank you :)


Solution

  • Issue

    You are creating and sorting arrays in the component body of a functional component, which is a side-effect and anti-pattern in React.

    export default function Quicksort() {
      var arr = new Array(50); // <-- side-effect
      for (var i = 0; i < 50; ++i) {
        arr[i] = Math.floor(Math.random() * Math.floor(400)); // <-- side-effect
      }
    
      console.log(arr); // <-- side-effect
      arr.sort(function (a, b) { // <-- side-effect
        return a - b;
      });
      console.log(arr); // <-- side-effect
    
      const mp = arr.map((num, idx) => {
        return <Bar key={idx} height={num} />;
      });
      return (
        <>
          <div className="layout">{mp}</div>
        </>
      );
    }
    

    enter image description here

    The entire body of a functional component IS the render function and your side-effects are being called during the "render phase" and messing with the output/returned UI in the "commit phase" when the ReactDOM is pushed to the browser DOM.

    Solution

    Create the array data outside the component, and thus outside the React component lifecycle, or put it in state so it is bound to the component lifecycle. Use an useEffect hook to correctly log the array when the component renders to the DOM.

    export default function Quicksort() {
      const [arr] = React.useState(
        [...Array(50)]
          .map(() => Math.floor(Math.random() * Math.floor(400)))
          .sort((a, b) => a - b)
      );
    
      React.useEffect(() => {
        console.log(arr);
      }, [arr]);
    
      const mp = arr.map((num, idx) => {
        return <Bar key={idx} height={num} />;
      });
    
      return (
        <>
          <div className="layout">{mp}</div>
        </>
      );
    }
    

    Edit react-component-taking-some-random-values