How to lazy load the data from useEffect?

110 Views Asked by At

So, in my code, i am loading the Select options and the options i am loading are based on the calculation of possibleSubnets for a netMask, for example /64 will have so many records in dropdown.

With my current implementation, it lags when it has to do so much of calculation in Options. Thus page becomes unresponsive.

import React, { useEffect, useState, useRef } from 'react';
import { Row, Col, Button, Form, Input, Space, Alert, Drawer, Divider } from 'antd';
import { useQuery, useMutation } from "@apollo/client";

import { TextInput, Select } from '../../components/pants-d';
import { NetmaskForm } from '../../components/SubnetBuilder';
import { possibleSubnets } from '../../components/SubnetBuilder/V4';
import cidrRegex from 'cidr-regex';
import { possibleSubnets as v6PossibleSubnets } from '../../components/SubnetBuilder/V6';
import debounce from 'lodash/debounce';

const { Option } = Select;

const subnet = require("../../entities/subnet");
const zone = require('../../entities/zone')

const SubnettingForm = ({ supernetId, networkAddress, onCreate, onClose }) => {

  const [errors, setErrors] = useState([])
  const [open, setOpen] = useState(true);
  const [childSubnets, setChildSubnets] = useState([]);
  const [showSelect, setShowSelect] = useState(false);

  const [createRecord, { data: createData, loading: createLoading, error: createErrors }] = useMutation(subnet.create, {
    onCompleted: ({ createSubnet: subnet }) => {
      onClose()
    },
    onError: (err) => {
      const message = err?.message

      setErrors([{ message: (message.charAt(0).toUpperCase() + message.slice(1)).replaceAll('\"', '') }])
    }
  });

  const { loading, error, data, refetch } = useQuery(subnet.GET_QUERY, { variables: { id: parseInt(supernetId) } });

  const [netmask, setNetmask] = useState();
  const [optionsLoading, setOptionsLoading] = useState(false); // Loading state for options
  const [subnetOptions, setSubnetOptions] = useState([]); // Options for the Select
  

  const supernet = data?.subnet?.networkAddress

  const [form] = Form.useForm();

  const isV4 = cidrRegex.v4({ exact: true }).test(data?.subnet?.networkAddress)

  useEffect(() => {
    let calculatedChildSubnets
    if (netmask) {
      if (isV4) {
        calculatedChildSubnets = possibleSubnets(data.subnet, netmask);
      } else {
        calculatedChildSubnets = v6PossibleSubnets(data.subnet, netmask)
      }
      setChildSubnets(calculatedChildSubnets);
      setShowSelect(true);
    } else {
      setShowSelect(false);
    }
  }, [netmask, supernet]);
  

  return (
    <Drawer
      title={`Create a subnet in ${data?.subnet?.networkAddress}`}
      onClose={onClose}
      width={520}
      visible={open}>
      <Form
        layout="vertical"
        form={form}
        name="subnet"
        onFinish={({ networkAddress, netmask, zone, ...values }) => {

          createRecord({ variables: { ...values, networkAddress: `${networkAddress}`, supernetId: supernetId } })

        }} >
        {errors && errors.map(error => {
          return (<><Alert type="error" message={error.message} /><br /></>)
        })}
        <Form.Item label="Netmask">
          <NetmaskForm limit={10} netmask={parseInt(data?.subnet?.networkAddress.split('/')[1])} onSelect={(v) => { setNetmask(v) }} defaultValue=' ' />
        </Form.Item>
        <Form.Item label="Subnet">
          <Select>
            {childSubnets.map((subnet) => (
              <Option key={subnet.id} value={subnet.id}>
                {subnet.networkAddress}
              </Option>
            ))}
          </Select>
        </Form.Item>
        <TextInput name="name" />

        <Row style={{ marginTop: '40px' }}>
          <Col span={24}>
            <Button type="secondary" onClick={e => { onClose() }} style={{ float: 'right', marginLeft: '20px' }}>
              Cancel
            </Button>
            <Button type="primary" htmlType="submit" style={{ float: 'right', marginLeft: '20px' }}>
              Submit
            </Button>
          </Col>
        </Row>
      </Form>
    </Drawer>
  )
}

export default SubnettingForm;

I am thinking, if we can lazy load or debounce the data on scroll in options, like load 10 options first and then load more when reached in the end of scroll.

0

There are 0 best solutions below