Сделайте доступной только одну строку в React Table 7.1.0

Я пытаюсь реализовать таблицу реагирования с возможностью выбора только одной строки за раз. Я просмотрел множество примеров для выбора нескольких строк в таблице реакции, но в моем случае пользователь может выбрать только одну строку, когда пользователь нажимает переключатель, но в настоящее время могут быть выбраны все строки. Может ли кто-нибудь помочь мне реализовать это?

введите описание изображения здесь


person Riten    schedule 08.07.2020    source источник
comment
Это обязательно проблема таблицы реакции? Я бы просто использовал для этого некоторое управление на уровне компонентов или глобальное состояние с использованием идентификаторов элементов.   -  person gazdagergo    schedule 08.07.2020
comment
@gazdagergo Мне нужно использовать таблицу реагирования для отображения флажка, переключать выбор флажка при нажатии на переключатель, поэтому нужно выполнить эти операции с таблицей реагирования, не могли бы вы подробнее рассказать о своих предложениях? Я как бы застрял на этом этапе ..   -  person Riten    schedule 08.07.2020
comment
Честно говоря, я не большой поклонник таблицы реакции. Вы можете очень легко настроить сложные таблицы, но вы тратите все это время, как только пытаетесь добавить настраиваемую функцию. Это был мой опыт.   -  person gazdagergo    schedule 09.07.2020
comment
@gazdagergo да, я согласен, но все остальные функции уже интегрированы с таблицей реагирования, только эта еще не завершена ... так что на данный момент это стало серьезной проблемой ... так что просто пытаюсь найти решение   -  person Riten    schedule 10.07.2020


Ответы (4)


Используя response-table 7.5.0, я собрал CodeSandbox с реакцией -таблица, которая функционально позволяет выбирать только одну строку за раз.

По сути, я заменил безоговорочно отрендеренный чекбокс:

Cell: ({ row }) => (
  <div>
    <IndeterminateCheckbox {...row.getToggleRowSelectedProps()} />
  </div>
)

с флажком для условного рендеринга:

Cell: ({ row }) => {
  if (
    rows.filter((row) => row.isSelected).length < 1 ||
    row.isSelected
  ) {
    return (
      <div>
        <IndeterminateCheckbox {...row.getToggleRowSelectedProps()} />
      </div>
    );
  } else {
    return (
      <div>
        <IndeterminateCheckbox
          checked={false}
          readOnly
          style={row.getToggleRowSelectedProps().style}
        />
      </div>
    );
  }
}

Я отфильтровал все объекты строк, чтобы проверить выбранные строки, а затем условно отобразил нормально работающий флажок таблицы реакций, если количество выбранных строк меньше 1 или если строка уже выбрана.

Если количество проверенных строк равно как минимум одной, а строка не выбрана, я визуализирую флажок только для чтения, который нельзя установить.

В идеале мне хотелось бы использовать встроенный selectedRowIds таблицы реакции вместо фильтрации по всем объектам строк, но я не мог понять, как реализовать useTable () таким образом, чтобы это позволяло мне ссылаются на него, поскольку он является производным от него.

Вот таблица реакции Code Selection CodeSandbox, от которого я разветвился. Вот соответствующая страница в их документации.

Позже я перенесу код во встроенный фрагмент кода.

person jwmcgettigan    schedule 19.08.2020
comment
очень полезный! должен быть принятый ответ :) - person Alfonso; 20.04.2021

Это простая реализация поведения, подобного радио, с useReducer, чтобы продемонстрировать, как использовать управление состоянием с таблицей.

const { useReducer } = React; // --> for inline use
// import React, { useReducer } from 'react';  // --> for real project


const reducer = (state, action) => {
  return { checkedId: action.id }
}

const App = () => {
  const [state, dispatch] = useReducer(reducer, {})
  
  const CheckBox = ({id}) => (
    <input
      id={id}
      onClick={() => dispatch({ id })}
      checked={state.checkedId === id}
      type="checkbox"
    />
  )

 
  return (
    <table border="1">
      <tr><td><CheckBox id="1" /></td><td>John</td></tr>
      <tr><td><CheckBox id="2" /></td><td>Doe</td></tr>
    </table>
  )
};


ReactDOM.render(<App />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>

person gazdagergo    schedule 09.07.2020

Вы также можете переопределить метод onChange в функции prop Cell (...).

https://react-table.tanstack.com/docs/api/useRowSelect#row-properties

getToggleRowSelectedProps: Function(props) => props
Use this function to get the props needed for a select row checkbox.
Props:
onChange: Function()
style.cursor: 'pointer'
checked: Bool
title: 'Toggle Row Selected'

Отдам песочницу позже, когда будет свободное время.

person yuushiro    schedule 01.10.2020

Я знаю, что это старый вопрос, но, возможно, кто-то сочтет это решение полезным. Начиная с версии 7, react-table предоставляет stateReducer, который можно использовать для отслеживания и изменения состояния таблицы. (до v7 было reducerHandlers, но я не углублялся в это). Вы можете изменить состояние следующим образом:

useTable(
    {
      columns,
      data,
      stateReducer: (newState, action) => {
          if (action.type === "toggleRowSelected") {
            newState.selectedRowIds = {
              [action.id]: true
            }
          }

          return newState;
      },
    }
    ...

Вот CodeSandbox с описанными изменениями.

person Ann    schedule 06.07.2021