Как заменить объект, содержащий реагирующие компоненты, одной строкой кода? - PullRequest
0 голосов
/ 17 января 2020

В нескольких компонентах у меня есть идентичная часть кода. Он предоставляет таблицы 'ant-design' со свойствами, необходимыми для фильтрации.

getColumnSearchProps = dataIndex => ({
    filterDropdown: ({
      setSelectedKeys,
      selectedKeys,
      confirm,
      clearFilters
    }) => (
      <div style={{ padding: 8 }}>
        <Input
          ref={node => {
            this.searchInput = node;
          }}
          placeholder={`Search ${dataIndex}`}
          value={selectedKeys[0]}
          onChange={e =>
            setSelectedKeys(e.target.value ? [e.target.value] : [])
          }
          onPressEnter={() => this.handleSearch(selectedKeys, confirm)}
          style={{ width: 188, marginBottom: 8, display: "block" }}
        />
        <Button
          type="primary"
          onClick={() => this.handleSearch(selectedKeys, confirm)}
          icon="search"
          size="small"
          style={{ width: 90, marginRight: 8 }}
        >
          Search
        </Button>
        <Button
          onClick={() => this.handleReset(clearFilters)}
          size="small"
          style={{ width: 90 }}
        >
          Reset
        </Button>
      </div>
    ),
    filterIcon: filtered => (
      <Icon type="search" style={{ color: filtered ? "#1890ff" : undefined }} />
    ),
    onFilter: (value, record) =>
      record[dataIndex]
        .toString()
        .toLowerCase()
        .includes(value.toLowerCase()),
    onFilterDropdownVisibleChange: visible => {
      if (visible) {
        setTimeout(() => this.searchInput.select());
      }
    },
    render: text => (
      <Highlighter
        highlightStyle={{ backgroundColor: "#ffc069", padding: 0 }}
        searchWords={[this.state.searchText]}
        autoEscape
        textToHighlight={text && text.toString()}
      />
    )
  });

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

columns = [
  {
      title: "Client",
      dataIndex: "client",
      sorter: (a, b) => {
        if (a.client && b.client) {
          return a.client.localeCompare(b.client);
        } else {
          return a.client;
        }
      },
      sortDirections: ["descend", "ascend"],
      ...this.getColumnSearchProps("client")
    }
]

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

Я пытался создать новую js функцию getColumnSearchProps в отдельном файле. Я заменил ref={node => { this.searchInput = node; }} на const searchInput = React.createRef();, но это привело к ошибке searchInput.select is not a function.

1 Ответ

0 голосов
/ 17 января 2020

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

Ошибка searchInput.select is not a function возникла из-за некомплитного пути - searchInput.select() вместо serachInput.current.select().

const getColumnSearchProps = (dataIndex, searchText) => {
  const searchInput = React.createRef();

  return {
    filterDropdown: ({
      setSelectedKeys,
      selectedKeys,
      confirm,
      clearFilters
    }) => (
      <div style={{ padding: 8 }}>
        <Input
          ref={searchInput}
          placeholder={`Search ${dataIndex}`}
          value={selectedKeys[0]}
          onChange={e =>
            setSelectedKeys(e.target.value ? [e.target.value] : [])
          }
          onPressEnter={() => this.handleSearch(selectedKeys, confirm)}
          style={{ width: 188, marginBottom: 8, display: "block" }}
        />
        <Button
          type="primary"
          onClick={() => this.handleSearch(selectedKeys, confirm)}
          icon="search"
          size="small"
          style={{ width: 90, marginRight: 8 }}
        >
          Search
        </Button>
        <Button
          onClick={() => this.handleReset(clearFilters)}
          size="small"
          style={{ width: 90 }}
        >
          Reset
        </Button>
      </div>
    ),
    filterIcon: filtered => (
      <Icon type="search" style={{ color: filtered ? "#1890ff" : undefined }} />
    ),
    onFilter: (value, record) =>
      record[dataIndex]
        .toString()
        .toLowerCase()
        .includes(value.toLowerCase()),
    onFilterDropdownVisibleChange: visible => {
      if (visible) {
        setTimeout(() => searchInput.current.select());
      }
    },
    render: text => (
      <Highlighter
        highlightStyle={{ backgroundColor: "#ffc069", padding: 0 }}
        searchWords={[searchText]}
        autoEscape
        textToHighlight={text && text.toString()}
      />
    )
  };
};

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