odd or even large number with react window instead of web worker
Tags: javascript, react, css, webworker
Published: 2022-03-09 20:18:22

React window works by only rendering part of a large data set (just enough to fill the viewport). This helps address some common performance bottlenecks.

1. It reduces the amount of work (and time) required to render the initial view and to process updates.

2. It reduces the memory footprint by avoiding over-allocation of DOM nodes
First write input with ant design:

```react
import PropTypes from "prop-types";
import React from "react";
import { Input as InputBase } from "antd";
import { Controller, useController } from "react-hook-form";
import classNames from "classnames";

const Input = ({
  name,
  value,
  message,
  control,
  register,
  classes,
  label,
  absolute,
  ...rest
}) => {
  const {
    field,
    fieldState: { error },
  } = useController({
    name,
    control,
    rules: register,
    defaultValue: value,
  });
  return (
    <div
      className={classNames("input", {
        input__absolute: absolute,
      })}
    >
      {label ? <label className="input__label">{label} :</label> : null}
      <InputBase
        className={classNames("input__field", [classes], {
          input__error: error,
        })}
        {...field}
        {...rest}
      />
      {error && <span className="input__message">{error.message}</span>}
    </div>
  );
};

Input.propTypes = {
  classes: PropTypes.any,
  control: PropTypes.any,
  errors: PropTypes.any,
  label: PropTypes.string,
  message: PropTypes.string,
  name: PropTypes.string,
  register: PropTypes.any,
  value: PropTypes.any,
};
export default Input;

```
then make button component

```react
import PropTypes from "prop-types";
import React from "react";
import { Button as ButtonBase } from "antd";
import classNames from "classnames";

const Button = ({
  type,
  classes,
  large,
  success,
  disabled,
  children,
  ...rest
}) => {
  return (
    <ButtonBase
      type={type}
      className={classNames(`button button__${type}`, [classes], {
        large: large,
        success: success,
        disabled: disabled,
      })}
      disabled={disabled}
      {...rest}
    >
      {children}
    </ButtonBase>
  );
};
Button.defaultProps = {
  type: "default",
  large: false,
  success: false,
  disabled: false,
};

Button.propTypes = {
  children: PropTypes.node.isRequired,
  classes: PropTypes.string,
  large: PropTypes.bool,
  ico: PropTypes.bool,
  success: PropTypes.bool,
  disabled: PropTypes.bool,
  type: PropTypes.oneOfType(
    [PropTypes.oneOf(["primary", "default", "text", "gradient"])],
    PropTypes.string.isRequired
  ),
};
export default Button;

```
then use these codes to take data from the user:

```html
      <form onSubmit={handleSubmit(onSubmit)} className="Home__formBox">
        <Input
          label="عدد"
          register={{
            required: {
              value: true,
              message: "Enter the number",
            },
          }}
          type="number"
          name="data"
          control={control}
        />
        <Button
          type="primary"
          classes="MasterSignUp__btn"
          htmlType="submit"
          disabled={loading ? true : false}
        >
          {loading ? "sending..." : "send"}
        </Button>
      </form>
```
then write shape component to check if the number is odd or even, show circle or square

```react

import React, { useEffect, useState } from "react";
import { FixedSizeGrid as Grid } from "react-window";
import InfiniteLoader from "react-window-infinite-loader";

const Shapes = ({ loadMore, number }) => {
  const Row = ({ index, style }) => (
    <div className={"circles"} style={style}></div>
  );
  const Row1 = ({ index, style }) => (
    <div className={"squares"} style={style}></div>
  );
  const [type, setType] = useState("");
  useEffect(() => {
    if (number % 2 == 0) {
      setType(true); //even
    } else {
      setType(false); //odd
    }
  }, [number]);
  const LOADING = 1;
  const LOADED = 2;
  let itemStatusMap = {};
  const isItemLoaded = (index) => !!itemStatusMap[index];
  const loadMoreItems = (startIndex, stopIndex) => {
    for (let index = startIndex; index <= stopIndex; index++) {
      itemStatusMap[index] = LOADING;
    }
    return new Promise((resolve) =>
      setTimeout(() => {
        for (let index = startIndex; index <= stopIndex; index++) {
          itemStatusMap[index] = LOADED;
        }
        resolve();
      }, 2500)
    );
  };
  return (
    <InfiniteLoader
      isItemLoaded={(index) => index < number}
      itemCount={number}
      loadMoreItems={loadMoreItems}
    >
      {({ onItemsRendered, ref }) => (
        <Grid
          columnCount={number / 10}
          columnWidth={40}
          rowCount={number}
          rowHeight={25}
          height={800}
          width={800}
          itemSize={50}
          onItemsRendered={onItemsRendered}
          ref={ref}
          className="Shapes"
        >
          {type ? Row : Row1}
        </Grid>
      )}
    </InfiniteLoader>
  );
};

export default Shapes;

```
then update the home page with this component:

```react
import React, { useState } from "react";
import { useForm } from "react-hook-form";
import Input from "./Input";
import Button from "./Button";
import Shapes from "./Shapes";

function Index() {
  const [loading, setLoading] = useState(false);
  const [number, setNumber] = useState(0);
  const {
    handleSubmit,
    control,
    register,
    reset,
    formState: { errors, isSubmitted },
  } = useForm();
  const onSubmit = (data) => {
    // setLoading(true);
    setNumber(data.data);
  };
  return (
    <div>
      <form onSubmit={handleSubmit(onSubmit)} className="Home__formBox">
        <Input
          label="number"
          register={{
            required: {
              value: true,
              message: "enter number",
            },
          }}
          type="number"
          name="data"
          control={control}
        />
        <Button
          type="primary"
          classes="MasterSignUp__btn"
          htmlType="submit"
          disabled={loading ? true : false}
        >
          {loading ? "sending..." : "send"}
        </Button>
      </form>
      <Shapes number={number} setLoading={setLoading} />
    </div>
  );
}

export default Index;

```