Cannot update a component (`AssignTeacherForAttendance`) while rendering a different component (`DataTable`)

My Code is :

import { getAuthToken } from '../../utils/auth';
import { API } from '../../config/api/api.config';
import axios from 'axios';
import { resHandlerNoSuccess, responseHandler } from '../../utils/responseHandler';
import { CCard, CCardBody, CCardTitle, CFormInput, CFormLabel } from '@coreui/react';
import { Button } from 'primereact/button';
import { DataTable } from 'primereact/datatable';
import { Column } from 'primereact/column';
import { Calendar } from 'primereact/calendar';
import { Dropdown } from 'primereact/dropdown';

import {
  Form,
  redirect,
  useActionData,
  useLoaderData,
  useNavigation,
  useSearchParams,
  useSubmit,
} from 'react-router-dom';
import { getStandardDropdownLoader } from '../standard/AddSection';
import React, { useCallback, useEffect, useState } from 'react';
import { getSectionDropdownLoader } from '../student/AddStudent';
import { classNames } from 'primereact/utils';

const SectionAccessTable = React.memo(({ sectionAccess, onAccessTypeSort }) => {
  return (
    <DataTable
      value={sectionAccess ? sectionAccess?.section_access : []}
      tableStyle={{ marginLeft: '4px', marginTop: '4px', borderTop: '1px solid  #cccccc' }}
      size="small"
      removableSort
      paginator
      rows={50}
      emptyMessage="No section access found"
    >
      <Column
        header="#"
        body={(data, options) => options.rowIndex + 1}
        style={{ width: '5%' }}
      ></Column>
      <Column field="standard" header="Standard"></Column>
      <Column field="section_name" header="Section"></Column>
      <Column field="faculty_name" header="Faculty"></Column>
      <Column field="user_type" header="User Type"></Column>
      <Column field="from" header="From" sortable></Column>
      <Column field="to" header="to" sortable></Column>
      <Column
        field="access_type"
        header="Access Type"
        sortable
        sortFunction={onAccessTypeSort}
      ></Column>
      <Column header="Action"></Column>
    </DataTable>
  );
});

const AssignTeacherForAttendance = () => {
  // getting hooks
  const { standards, section, faculty, sectionAccess } = useLoaderData();
  const actionData = useActionData();
  let [searchParams, setSearchParams] = useSearchParams();
  let submit = useSubmit();
  // setting state
  const [perPage, setPerPage] = useState(50);
  const [pageNumber, setPageNumber] = useState(1);
  const [sortField, setSortField] = useState('');
  const [sortOrder, setSortOrder] = useState('ASC');

  // Setting state for form data
  const [standardSelected, setStandardSelected] = useState(null);
  const [sectionSelected, setSectionSelected] = useState(null);
  const [facultySelected, setFacultySelected] = useState(null);
  const [accessTypeSelected, setAccessTypeSelected] = useState(null);
  const [fromDate, setFromDate] = useState(null);
  const [toDate, setToDate] = useState(null);
  // setting forms value
  const accessType = [
    { access_type: 'same_day' },
    { access_type: 'all_day' },
    { access_type: 'range_day' },
  ];
  // Checking if initial render
  useEffect(() => {
    if (actionData?.success === true) {
      setStandardSelected(null);
      setSectionSelected(null);
      setFacultySelected(null);
      setAccessTypeSelected(null);
      setFromDate(null);
      setToDate(null);
    }
    // setSearchParams({});
  }, [actionData]);
  // Setting search params when standard is selected
  useEffect(() => {
    if (!standardSelected) return;
    setSearchParams({ standard_id: standardSelected });
  }, [standardSelected]);
  // submitting form
  const onAssignFaculty = useCallback(() => {
    submit(
      {
        section_id: sectionSelected,
        faculty_id: facultySelected,
        access_type: accessTypeSelected,
        from: fromDate,
        to: toDate,
      },
      { method: 'post', encType: 'application/json' },
    );
  }, [sectionSelected, facultySelected, accessTypeSelected, fromDate, toDate, submit]);
  // on access type sorting
  const onAccessTypeSort = useCallback(({ data, field, order }) => {
    console.log('>> sorting called');
    const orderNow = order === 1 ? 'ASC' : order === -1 ? 'DESC' : '';
    setSortField(field);
    setSortOrder(orderNow);
  }, []);
  return (
    <>
      <div>
        <form className="flex justify-content-start p-1 flex-wrap">
          <div className="pr-1">
            <Dropdown
              value={standardSelected}
              onChange={(e) => setStandardSelected(e.value)}
              options={standards ? standards : []}
              placeholder="Select standard"
              className={`w-full md:w-11rem p-inputtext-sm`}
              optionValue="id"
              optionLabel="standard"
            />
          </div>
          <div className="pr-1">
            <Dropdown
              value={sectionSelected}
              onChange={(e) => setSectionSelected(e.value)}
              options={section ? section : []}
              placeholder="Select section"
              className="md:w-11rem p-inputtext-sm"
              optionValue="id"
              optionLabel="section_name"
            />
          </div>
          <div className="pr-1">
            <Dropdown
              value={facultySelected}
              onChange={(e) => setFacultySelected(e.value)}
              options={faculty ? faculty : []}
              placeholder="Select Faculty"
              optionLabel="full_name"
              className="md:w-11rem p-inputtext-sm"
              optionValue="id"
            />
          </div>
          <div className="pr-1">
            <Dropdown
              value={accessTypeSelected}
              onChange={(e) => setAccessTypeSelected(e.value)}
              options={accessType ? accessType : []}
              placeholder="Access Type"
              className="md:w-10rem p-inputtext-sm"
              optionValue="access_type"
              optionLabel="access_type"
            />
          </div>
          <div className="pr-1">
            <Calendar
              value={fromDate}
              onChange={(e) => setFromDate(e.value)}
              className="md:w-6rem p-inputtext-sm "
              placeholder="From"
              // touchUI
            />
          </div>
          <div className="pr-1">
            <Calendar
              value={toDate}
              onChange={(e) => setToDate(e.value)}
              className="md:w-6rem p-inputtext-sm "
              placeholder="To"
              // touchUI
            />
          </div>
          <Button
            label="Assign"
            severity="success"
            type="button"
            // disabled={isSubmitting}
            raised
            // loading={isSubmitting}
            size="small"
            onClick={onAssignFaculty}
          />
        </form>
        <SectionAccessTable sectionAccess={sectionAccess} onAccessTypeSort={onAccessTypeSort} />
      </div>
    </>
  );
};
export default AssignTeacherForAttendance;

async function getFacultyDropdownLoader() {
  const token = getAuthToken();
  const facultyDropdownResponse = await axios({
    url: API.endpoint + '/user/faculty-dropdown',
    headers: {
      'Content-Type': 'application/json',
      Authorization: token,
    },
    validateStatus: () => true,
  });
  return resHandlerNoSuccess(facultyDropdownResponse);
}

async function getSectionAccessList({
  sort_field,
  sort_order,
  per_page,
  page_number,
  search_term,
}) {
  const token = getAuthToken();
  const response = await axios({
    url: API.endpoint + '/section-access/list-all',
    params: {
      per_page: per_page ? per_page : 50,
      sort_order: sort_order ? sort_order : 'ASC',
      sort_field: sort_field ? sort_field : '',
      page_number: page_number ? page_number : 1,
    },
    headers: {
      'Content-Type': 'application/json',
      Authorization: token,
    },
    validateStatus: () => true,
  });
  return resHandlerNoSuccess(response);
}

export async function loader({ request }) {
  const url = new URL(request.url);
  const standardId = url.searchParams.get('standard_id');
  const per_page = url.searchParams.get('per_page');
  const sort_order = url.searchParams.get('sort_order');
  const sort_field = url.searchParams.get('sort_field');
  const page_number = url.searchParams.get('page_number');
  const facultyDropdown = await getFacultyDropdownLoader();
  const standardList = await getStandardDropdownLoader();
  const sectionAccessList = await getSectionAccessList({
    per_page,
    sort_order,
    sort_field,
    page_number,
  });
  if (facultyDropdown.redirect) return redirect(facultyDropdown.redirect);
  if (standardList.redirect) return redirect(standardList.redirect);
  if (sectionAccessList.redirect) return redirect(sectionAccessList.redirect);
  if (standardId) {
    const sectionDropdownGot = await getSectionDropdownLoader(standardId);
    if (sectionDropdownGot.redirect) return redirect(sectionDropdownGot.redirect);
    return {
      section: sectionDropdownGot.data,
      standards: standardList.data,
      faculty: facultyDropdown.data?.faculty,
      sectionAccess: sectionAccessList.data,
    };
  }
  return {
    standards: standardList.data,
    faculty: facultyDropdown.data?.faculty,
    sectionAccess: sectionAccessList.data,
  };
}

export async function action({ request, params }) {
  const token = getAuthToken();
  const data = await request.json();
  const responseGot = await axios.post(
    API.endpoint + '/section-access/assign-for-attendance',
    {
      ...data,
    },
    {
      headers: {
        'Content-Type': 'application/json',
        Authorization: token,
      },
      validateStatus: () => true,
    },
  );
  if (!responseGot) return null;
  const responseHandled = responseHandler(responseGot);
  if (responseHandled.redirect) return redirect(responseHandled.redirect);
  return responseHandled.data;
}

I am getting this warning :
enter image description here

I have gone through :
github 1
stackoverflow 2
stackoverflow 3
stackoverflow 4

I am not able to find any solution please please help me.

What I have done :

  1. Added callback in set filter function
  2. Moved DataTable into new component.
  3. Used React.memo for only call for neccessary props in section access table.

Please help me. Thank you in advance.

  • I haven’t reviewed your whole code snippet but one red flag I have immediately noticed is that you call useState setters in the AssignTeacherForAttendance component render. You might want to look at the if (isInitialStandard) { ... } statement and the two setter functions it is wrapping, these should most likely be called inside a useEffect with an appropriate dependency array.

    – 

  • Hi @JacobSmit Thank you so much for letting me know about my bad state management, I just edited code here and improved it as you said. But still getting same error. Please help me out. I am new in coding and struggling through this. Thanks in advance.

    – 

Leave a Comment