Отображение / скрытие элементов массива в зависимости от условия: ReactJS - PullRequest
0 голосов
/ 07 января 2020

У меня есть сетка, где в столбце может быть массив элементов. Все, что мне нужно, это реализовать решение, в котором если в этом столбце содержится более 1 элемента, необходимо отобразить «Показать больше», а при щелчке на нем должны отобразиться все элементы (через запятую) и создать ссылку «Показать меньше», которая бы скрыть все элементы, кроме первого. Также, когда нет данных, просто укажите «Не доступно» для этого значения столбца. Я использую таблицу реакции для целей сетки

Я пробовал следующее: https://codesandbox.io/s/react-table-row-table-mpk9s

import * as React from "react";
import { render } from "react-dom";
import DataGrid from "./DataGrid";
import ShowMore from "./ShowMore";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
      columns: [],
    };
  }

  componentDidMount() {
    this.getData();
    this.getColumns();
  }

  showMoreUtility = arr => {
    return <ShowMore value={arr} />;
  };

  getData = () => {
    const data = [
      { firstName: "Jack", status: "Submitted", items: [1, 2, 3, 4] },
      { firstName: "Simon", status: "Pending", items: [1, 2] },
      { firstName: "Syls", status: "Pending", items: [1, 2] },
      { firstName: "Pete", status: "Approved", items: [] }
    ];
    this.setState({ data });
  };

  getColumns = () => {
    const columns = [
      {
        id: "1",
        Header: "First Name",
        accessor: "firstName"
      },
      {
        id: "2",
        Header: "Status",
        accessor: "status"
      },
      {
        id: "3",
        Header: "Items",
        accessor: arr => this.showMoreUtility(arr.items)
      }
    ];
    this.setState({ columns });
  };

  render() {
    return (
      <>
        <DataGrid
          data={this.state.data}
          columns={this.state.columns}
        />
      </>
    );
  }
}


Ответы [ 2 ]

1 голос
/ 07 января 2020

На основе кода из связанной изолированной программной среды вы можете добавить свойство Cell в столбец items и передать значение вашему компоненту ShowMore:

{
  Header: "Items",
  accessor: "items",
  Cell: row => (
    <ShowMore value={row.value} />
  )
}

, а затем в ShowMore component добавьте || !value.length к вашему условию, чтобы вернуть Not Available при отсутствии данных

if (value === undefined || value === null || !value.length) {
  return 'Not Available';
}

Также добавьте событие onClick в div, чтобы обновить значение isTruncated и изменить отображаемые данные:

function handleClick() {
  truncate(!isTruncated);
}

return (
  <div onClick={handleClick}>
    {
      isTruncated
      ?  <span>
          {value[0]} 
          {value.length > 1 && ' Show more'}
         </span>
      :  <span>
          {value.join(',')} 
          {value.length > 1 && ' Show less'}
         </span>
    }
  </div>
);

Рабочий пример :

Edit React-Table-Row-Table

1 голос
/ 07 января 2020

Ты почти там. Компонент ShowMore нуждается в некоторых модификациях, а столбец items также неверен.

Я написал пример рабочего компонента ShowMore, чтобы показать, как это можно сделать:

const ShowMore = props => {
  const { value } = props;
  const [isTruncated, setTruncate] = useState(true);
  const toggleTruncate = () => setTruncate(!isTruncated);
  if (value === undefined || value === null) {
    return null;
  }

  if (value.length === 0) {
    return 'Unavailable'
  }

  return (
    <div>
      {isTruncated ? value[0] : value}
      <span onClick={toggleTruncate}>
        {isTruncated ? "Show more" : "Show less"}
      </span>
    </div>
  );
};

При таком изменении компонента ShowMoreItem он будет работать, но в соответствии со спецификациями react-table это не правильный способ его использования. Атрибут accessor должен использоваться для получения правильных данных вместо визуализации пользовательского компонента. Для пользовательского рендеринга вы можете использовать атрибут Cell.

Изменить столбцы элементов следующим образом:

accessor: "items", // This will get the 'items' attribute from the row.
Cell: row => {
  // This will render the ShowMore component with the correct value.
  return <ShowMore value={row.value} />;
}
...