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

Beigisaba
3 min readMar 9, 2022

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 wright 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;

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;

then use these codes to take data from the user:

<form onSubmit={handleSubmit(onSubmit)} className="Home__formBox">
<Input
label="number"
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

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:

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="عدد"
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;

--

--