【问题标题】:React Table - radio input for useRowSelectReact Table - useRowSelect 的单选输入
【发布时间】:2020-07-06 01:27:27
【问题描述】:

如何在 React Table 中为可选表使用单选输入而不是复选框?

有一个复选框而不是单选按钮的示例:https://github.com/tannerlinsley/react-table/blob/master/examples/row-selection/src/App.js

将 IndeterminateCheckox 更改为使用单选输入不起作用,因为 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} />
    );
  });


它看起来正确,但没有将正确的选择状态传回:

【问题讨论】:

  • 当您选择不同的选项时会发生什么?您是否在开发工具中看到组件/组件状态的任何更改?此外,...rest 中包含什么——它是否包含您期望的所有内容?看起来很可能您的表实现很好,并且错误在您的状态实现中。
  • 如果您仔细查看 userRowSelect 示例,React Table 为被点击的行存储一个“选择”状态。它假定使用复选框,因此它允许通过 ...rest 传递多个选择。我认为最简单的解决方案是在数据单元内实现自定义无线电输入,而不是使用 useRowSelect,我只是认为其他人之前会遇到这种情况。

标签: javascript reactjs react-table


【解决方案1】:

快速浏览了一下。试试这个:

  • 拥有 rowId 的状态
const [selectedRowId, setSelectedRowId] = useState(null);
  • autoResetSelectedRows: false, 传递给useTable 函数
  • 手动为收音机编写一个点击处理程序

    onClick={() =&gt; setSelectedRowId(row.id)}

我在这里整理了工作代码。 https://codesandbox.io/s/objective-faraday-gzf7y

注意事项:

【讨论】:

  • 我试图一次只选择 1 行,我发现你的代码只有在包含 &lt;React.StrictMode&gt; 时才会这样做,你能解释一下为什么吗?
  • React.StrictMode 不是必需的。虽然很好。使用 toggleAllRowsSelected 将所有行设置为未选中。在上面的示例中,将 toggleAllRowsSelected 添加到 Cell 逻辑下的第 92 行,然后在 updateSelectedRowId 之前 onclick do toggleAllRowsSelected(false)
【解决方案2】:

如果有人还在为此苦苦挣扎,我找到了不同的解决方案。

IndeterminateCheckbox 相同,输入类型略有变化:

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} />
            </>
        );
    }
);

然后onClick我们取消选择所有行,并选择“点击”行。 :)

 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
                ]);
            }
        );

【讨论】:

  • 这不起作用,您将能够选择多个单选按钮。
【解决方案3】:

根据之前的回答,下面的解决方案有一些改进

  1. 将复选框更改为单选输入

    IndeterminateCheckbox 组件内部

    Remove  <input type="checkbox" ref={resolvedRef} {...rest} />*/}
    Add     <input type="radio" ref={resolvedRef} {...rest} />
    
  2. a) 如果您想最初自动选择任何行,请设置初始状态

    b) 取消选择所有单选按钮

    c) row.getToggleRowSelectedProps().checked 给出该行单选按钮的当前状态。因此,相应地切换该值。即

    如果 checked -> 更改为 unchecked

    如果未选中 -> 改为选中

    // 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
                        ]);
                        })
    

【讨论】:

  • 如何禁用全选并从标题行中删除单选按钮?
猜你喜欢
  • 1970-01-01
  • 2023-02-08
  • 1970-01-01
  • 1970-01-01
  • 2019-08-11
  • 2021-11-25
  • 2021-12-27
  • 2020-04-15
  • 1970-01-01
相关资源
最近更新 更多