Search code examples
javascriptreactjsreact-tablereact-window

Having trouble with radio buttons forgetting its state when using React-Window


I have follow a couple of examples using react-table and react-window so far so good, but I need the table to have select boxes to select individual or grouped rows as well as a radio-like button to be able to toggle information for a row, I manage to implement this but when I scroll up or down the selected radio button looses its selected state, as shown below enter image description here

As you can see when I select a row its ID is displayed below the table but when I scroll and move the row away from the view the radio button looses its checked state.

I have an example of the code here


Solution

  • At first, you must update your RadioCheckbox component

    const RadioCheckbox = ({ cell, checked, handleChange }) => {
      return (
        <input
          type="radio"
          onChange={handleChange}
          value={cell.row.id}
          checked={checked}
        />
      );
    };
    

    and then, you must add a function to handle your change in App component and change your default state of selectedRadio

    const [selectedRadio, setSelectedRadio] = useState([]);
    
    const handleSelectedRadioChange = ({ currentTarget }) => {
        if (selectedRadio.includes(currentTarget.value)) {
          setSelectedRadio(
            selectedRadio.filter((item) => item === currentTarget.value)
          );
        } else {
          setSelectedRadio(currentTarget.value);
        }
     }; 
    

    and for the last step update the dependencies of your columns useMemo in App with [selectedRadio] and you must update your Cell render

    const columns = React.useMemo(
        () => [
          {
            id: "radio",
            Header: "on/off",
            Cell: (props) =>
              notAllowedRows.includes(props.cell.row.index) ? null : (
                <div>
                  <RadioCheckbox
                    cell={props.cell}
                    checked={selectedRadio.includes(props.cell.row.id)}
                    handleChange={handleSelectedRadioChange}
                  />
                </div>
              ),
            width: 60
          },
          {
            Header: "Row Index",
            accessor: (row, i) => i,
            width: 95
          },
          {
            Header: "First Name",
            accessor: "firstName"
          },
          {
            Header: "Last Name",
            accessor: "lastName"
          },
          {
            Header: "Age",
            accessor: "age",
            width: 50
          },
          {
            Header: "Visits",
            accessor: "visits",
            width: 60
          }
        ],
        [selectedRadio]
      );