DEV Community

Saba beigi
Saba beigi

Posted on • Edited on

odd or even large number with react window instead of web worker

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:

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;

Enter fullscreen mode Exit fullscreen mode

then make button component

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;

Enter fullscreen mode Exit fullscreen mode

then use these codes to take data from the user:

      <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>
Enter fullscreen mode Exit fullscreen mode

then write shape component to check if the number is odd or even, show circle or square


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;

Enter fullscreen mode Exit fullscreen mode

then update the home page with this component:

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;

Enter fullscreen mode Exit fullscreen mode

Top comments (0)