admin管理员组

文章数量:1291199

How can I use radio inputs instead of checkboxes for a selectable table in React Table?

There is an example for checkboxes but not radio buttons: .js

Changing the IndeterminateCheckox to use a radio input doesn't work as the selection state is not updated in React Table:

const IndeterminateCheckbox = React.forwardRef(({ indeterminate, ...rest }, ref) => {
    const defaultRef = React.useRef();
    const resolvedRef = ref || defaultRef;

    useEffect(() => {
      resolvedRef.current.indeterminate = indeterminate;
    }, [resolvedRef, indeterminate]);

    return <input name="select-radio" type="radio" ref={resolvedRef} {...rest} />
    );
  });


It looks correct but does not pass the correct selection state back:

How can I use radio inputs instead of checkboxes for a selectable table in React Table?

There is an example for checkboxes but not radio buttons: https://github./tannerlinsley/react-table/blob/master/examples/row-selection/src/App.js

Changing the IndeterminateCheckox to use a radio input doesn't work as the selection state is not updated in React Table:

const IndeterminateCheckbox = React.forwardRef(({ indeterminate, ...rest }, ref) => {
    const defaultRef = React.useRef();
    const resolvedRef = ref || defaultRef;

    useEffect(() => {
      resolvedRef.current.indeterminate = indeterminate;
    }, [resolvedRef, indeterminate]);

    return <input name="select-radio" type="radio" ref={resolvedRef} {...rest} />
    );
  });


It looks correct but does not pass the correct selection state back:

Share Improve this question asked Mar 25, 2020 at 13:30 AlexAlex 2,8003 gold badges29 silver badges49 bronze badges 2
  • What happens when you select different options? Do you see any changes to the ponent / ponent state in your dev tools? Also, what's included in ...rest -- does it include everything you expect? It seems most likely that your table implementation is fine and the bug is in your state implementation. – the holla Commented Apr 2, 2020 at 21:29
  • If you take a closer look at the useRowSelect example React Table stores a 'selected' state for the row which was clicked. It assumes the use of checkboxes so it allows for multiple selections to be passed down through ...rest. I think the easiest solution to this would be to implement custom radio inputs inside a data cell rather than using useRowSelect, I just thought someone else would have run into this before. – Alex Commented Apr 3, 2020 at 12:32
Add a ment  | 

3 Answers 3

Reset to default 3 +50

Had a quick look. Try this:

  • Have a state for the rowId
const [selectedRowId, setSelectedRowId] = useState(null);
  • Pass autoResetSelectedRows: false, to useTable function
  • Write a click handler for the radios by hand

    onClick={() => setSelectedRowId(row.id)}

I have put together the working code here. https://codesandbox.io/s/objective-faraday-gzf7y

Notes:

  • There might be small issues with rapidly changing value of selectedFlatRows. I haven't fully researched this issue but I found https://github./tannerlinsley/react-table/issues/1740 . The issue says fixed but i am not pletely sure.
  • If you have issue with grabbing row data, try and see if the below links might be helpful How to get React Table Row Data Onclick https://codesandbox.io/s/tannerlinsleyreact-table-row-selection-hoisted-b4dvq?from-embed Select row on click react-table

Based on previous answers, the solution below is with some improvements

  1. Change Checkbox to Radio Input

    Inside IndeterminateCheckbox Component

    Remove  <input type="checkbox" ref={resolvedRef} {...rest} />*/}
    Add     <input type="radio" ref={resolvedRef} {...rest} />
    
  2. a) Set the initial state if you want to autoselect any row initially

    b) Deselect all the radio buttons

    c) row.getToggleRowSelectedProps().checked give the current state of the radio button of that row. So toggling that value accordingly. i.e

    if checked -> change to unchecked and

    if unchecked -> change to checked

    // This selectedRowIds state gives the information about which row is selected currently.
    const{state: { selectedRowIds }}=useTable(
    {
     ....
     initialState: {
          columns,
          data,
          selectedRowIds: { 2: true },  //a) I want my second row to be autoselected initially
       },
     },
     useRowSelect,
         hooks => {
             hooks.visibleColumns.push(columns => [
                 {
                     id: "selection",                    
                     Cell: ({ row, toggleAllRowsSelected, toggleRowSelected }) => {                      
                        const currentState = row.getToggleRowSelectedProps();
                        return (
                           <IndeterminateCheckbox
                              {...currentState}
                              onClick={() => {
                                // b)
                                  toggleAllRowsSelected(false);
                                // c)
                                  toggleRowSelected(row.id, !currentState.checked);
                          }} />)
    
                        }},
                          ...columns
                        ]);
                        })
    

In case someone is still struggling with this, I found different solution.

IndeterminateCheckbox is same with slight change for input type:

const IndeterminateCheckbox = React.forwardRef(
    ({ indeterminate, ...rest }, ref) => {
        const defaultRef = React.useRef();
        const resolvedRef = ref || defaultRef;

        React.useEffect(() => {
            resolvedRef.current.indeterminate = indeterminate;
        }, [resolvedRef, indeterminate]);

        return (
            <>
                {/*<input type="checkbox" ref={resolvedRef} {...rest} />*/}
                <input type="radio" ref={resolvedRef} {...rest} />
            </>
        );
    }
);

Then onClick we deselect all rows, and select "clicked" row. :)

 const {
            getTableProps,
            getTableBodyProps,
            headerGroups,
            rows,
            prepareRow,
            toggleAllRowsSelected,
            toggleRowSelected,
            state: { selectedRowIds },
        } = useTable(
            {
                columns,
                data,
            },
            useRowSelect,
            hooks => {
                hooks.visibleColumns.push(columns => [
                    // Let's make a column for selection
                    {
                        id: "selection",
                        // The cell can use the individual row's getToggleRowSelectedProps method
                        // to the render a checkbox
                        Cell: ({ row }) => {
                            return (
                                <div>
                                    <IndeterminateCheckbox
                                        {...row.getToggleRowSelectedProps()}
                                        onClick={() => {
                                            toggleAllRowsSelected(false);
                                            toggleRowSelected(row.id, true);
                                        }}
                                    />
                                </div>
                            );
                        }
                    },
                    ...columns
                ]);
            }
        );

本文标签: javascriptReact Tableradio input for useRowSelectStack Overflow