React state update not reflected in checked attribute of <input> elements

37 Views Asked by At

I'm working on a React component that includes a set of radio buttons. Each radio button's checked attribute is determined by a function isIdSelected, which checks if the radio button's id is included in a state variable selectedId. When a radio button is clicked, I update selectedId with the setSelectedId function. However, I'm finding that the checked attribute of the radio buttons isn't updating as expected when selectedId changes. I've confirmed that selectedId is being updated correctly with a useEffect hook. Can anyone help me understand why the checked attribute isn't reflecting the updated selectedId value?

import React, { useState, useRef, useEffect, useMemo } from 'react';
import { useTable, usePagination, useFilters, useRowSelect } from 'react-table';
import { Table, Modal, Button, Form } from 'react-bootstrap';

function DynamicTableComponent({ table, many, values, editable }) {
  let ids = Array.isArray(values) ? values : [values];
  const checkboxRef = useRef();
  const [selectedRow, setSelectedRow] = useState(null);
  const [selectedId, setSelectedId] = useState(ids);

  const handleRadioClick = (id) => {
    id = [id];
    setSelectedId(id);
  };
  
  const isIdSelected = (id) => {
    console.log(selectedId);
    // console.log(`rowId = ${id}, selectedRow = ${selectedId}`);
    const isSelected = selectedId.includes(id);
    return isSelected;
  };

  let columns = useMemo(
    () =>
      [
        {
          Header: 'id',
          accessor: 'id0'
        },
        ...table.field_info
          .filter(field => !['created_at', 'updated_at', 'deleted_at'].includes(field.name))
          .map((field, index) => ({
            Header: field.name,
            accessor: field.name,
          }))
      ],
    [table.field_info]
  );

  const data = useMemo(
    () =>
      table.model_instances.results.map((record, index) => {
        const row = {};
        table.field_info.forEach((field) => {
          if (field.name !== 'created_at' && field.name !== 'updated_at' && field.name !== 'deleted_at') {
            row[field.name] = record[field.name];
          }
        });
        row.id0 = index + 1;
        return row;
      }),
    [table.field_info, table.model_instances.results]
  );

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    selectedFlatRows,
    page,
    canPreviousPage,
    canNextPage,
    pageOptions,
    pageCount,
    gotoPage,
    nextPage,
    previousPage,
    setPageSize,
    toggleRowSelected,
    state: { pageIndex, pageSize, selectedRowIds },
  } = useTable(
    {
      columns,
      data,
      initialState: { pageIndex: 0, pageSize: 10, hiddenColumns: ['id'] },
    },
    useFilters,
    usePagination,
    useRowSelect,
    hooks => {
        hooks.visibleColumns.push(columns => [
          {
            id: 'selection',
            Header: ({ getToggleAllRowsSelectedProps }) =>
              many ? (
                <input
                  type="checkbox"
                  disabled={!editable}
                  {...getToggleAllRowsSelectedProps({ indeterminate: undefined })}
                  ref={checkboxRef}
                />
              ) : null,
              Cell: ({ row }) => (
                many ?
                <input
                  type={'checkbox'}
                  name={'unique'}
                  disabled={!editable}
                  {...row.getToggleRowSelectedProps({ indeterminate: undefined })}
                /> :
                <input
                  key={selectedId} 
                  type={'radio'}
                  name={'unique'}
                  checked={isIdSelected(row.original.id)}
                  onChange={() => handleRadioClick(row.original.id)}
                  // defaultChecked={isRowSelected(row.id)}
                  disabled={!editable}
                />
              ),
            },
          ...columns,
        ]);
      }    
  );

  useEffect(() => {
    if (checkboxRef.current) {
      checkboxRef.current.indeterminate =
        selectedFlatRows.length > 0 && selectedFlatRows.length !== page.length;
    }
    console.log(selectedId);
    if (values) {
      let ids = Array.isArray(values) ? values : [values];
      ids.forEach(id => {
        const row = page.find(row => row.original.id === id);
        if (row) {
          // toggleRowSelected(id, true)
          // many ? toggleRowSelected(id, true) : handleRadioClick(row.id);
        }
      });
    }
  }, [selectedFlatRows, page, selectedId]);
// Rest of code
0

There are 0 best solutions below