Как метод React, связанный в конструкторе, может потерять свою ограниченность при передаче в качестве параметра? - PullRequest
1 голос
/ 11 июля 2019

Вот коды для этого вопроса: https://codesandbox.io/s/rdg-grouping-81b1s

Я использую React-Data-Grid для рендеринга таблицы. Я отрисовываю ReactDataGrid с двумя столбцами, и когда вы нажимаете на текст GROUP в ячейке заголовка, вы группируете по этому столбцу.

Чтобы иметь возможность иметь настраиваемую ячейку заголовка с этим текстом GROUP, я использую свойство headerRenderer в объекте, определяющем столбцы.

Значение, переданное этому свойству, является функцией, которая принимает обработчик onClick в качестве параметра и возвращает функциональный компонент React, который использует этот обработчик onClick.

Параметр onClick - это просто метод исходного компонента React, и он связан в конструкторе компонента.

Как видите, я использую это свойство headerRenderer дважды, один раз для каждого столбца. Однако для первого столбца я снова связываю функцию параметра с компонентом React. Для второго столбца у меня нет, и это вызывает ошибку, когда я пытаюсь щелкнуть текст GROUP для этого столбца. См. Изображение ошибки ниже.

У меня вопрос: почему я должен связываться, если я уже связал функцию в конструкторе?

import React from 'react';
import './App.css';
import ReactDataGrid from 'react-data-grid';
import { Data } from 'react-data-grid-addons';

const HeaderRowRenderer = function(props) {
  return (
    <div
      style={{
        backgroundColor: 'red',
        paddingLeft: 10,
        height: '100%',
        padding: 0,
        display: 'flex',
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'space-between',
      }}
    >
      <span>{props.column.name}</span>
      <span onClick={props.onClick}>GROUP</span>
    </div>
  );
};

const HeaderRenderer = function(groupBy, onClick) {
  return function(props) {
    return (
      <HeaderRowRenderer
        {...props}
        onClick={function() {
          onClick(groupBy);
        }}
      />
    );
  };
};

const rows = [{ productname: 'Beef', quantity: 5 }, { productname: 'Veggies', quantity: 10 }];

class App extends React.Component {
  columns = [
    {
      key: 'productname',
      name: 'Product',
      width: 200,
      headerRenderer: HeaderRenderer('productname', this.groupBy.bind(this)),
    },
    {
      key: 'quantity',
      name: 'Quantity',
      headerRenderer: HeaderRenderer('quantity', this.groupBy),
    },
  ];

  constructor(props) {
    super(props);
    this.state = {
      groupBy: new Set([]),
    };
    this.groupBy = this.groupBy.bind(this);
  }

  groupBy(group) {
    const newSet = new Set(this.state.groupBy);
    if (newSet.has(group)) {
      newSet.delete(group);
    } else {
      newSet.add(group);
    }
    this.setState({ groupBy: newSet });
  }

  render() {
    const groupBy = Array.from(this.state.groupBy);
    // const rows = this.props.orderItems;

    const groupedRows = Data.Selectors.getRows({
      rows: rows,
      groupBy,
    });
    return (
      <div>
        <ReactDataGrid
          columns={this.columns}
          rowGetter={i => groupedRows[i]}
          rowsCount={groupedRows.length}
          minHeight={650}
        />
      </div>
    );
  }
}

export default App;

Я посмотрел код React-Data-Grid и считаю, что headerRenderer реквизит называется следующим образом:

  getCell() {
    const { height, column, rowType } = this.props;
    const renderer = this.props.renderer || SimpleCellRenderer;
    if (isElement(renderer)) {
      // if it is a string, it's an HTML element, and column is not a valid property, so only pass height
      if (typeof renderer.type === 'string') {
        return React.cloneElement(renderer, { height });
      }
      return React.cloneElement(renderer, { column, height });
    }
    return React.createElement(renderer, { column, rowType });
  }

Я не очень знаком с тем, как функция, которая была связана с использованием bind, а затем передана, может утратить эту ограниченность. Это происходит в результате React.cloneElement, или что может быть причиной этого?

Error

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...