首页 > 解决方案 > 我在使用 React 和 ant-design Table 组件时遇到了一些令人困惑的行为

问题描述

出于某种原因,我必须使 Table 组件的“列”道具有状态。然后发生了一些意想不到的错误。

以下代码工作正常,如预期的那样:

import React, { useEffect, useState } from 'react'
import { Modal, Table, Input, Button, Divider, Checkbox } from 'antd'

function App() {
  const [searchWord, setSearchWord] = useState('')
  const [items, setItems] = useState([])
  const [loading, setLoading] = useState(false)
  const [selectedItems, setSelectedItems] = useState([])

  const initColumns = [
    {
      title: <a onClick={selectAll}>Select All</a>,
      render: (_, record) => (
        <Checkbox
          checked={selectedItems.includes(record)}
          onChange={(e) => select(e.target.checked, record)}
        />
      ),
      key: 'select',
      width: 100,
      align: 'center',
    },
    {
      title: 'ID',
      dataIndex: 'objectID',
      key: 'objectID',
    },
    {
      title: 'author',
      dataIndex: 'author',
      key: 'author',
    },
    {
      title: 'title',
      dataIndex: 'title',
      key: 'title',
    },
    {
      title: 'comments',
      dataIndex: 'num_comments',
      key: 'comments',
    },
  ]

  function selectAll() {
    if (selectedItems.length === items.length) {
      setSelectedItems([])
    } else {
      setSelectedItems([...items])
    }
  }

  function select(checked, item) {
    if (checked) {
      setSelectedItems((selectedItems) => selectedItems.concat([item]))
    } else {
      setSelectedItems((selectedItems) =>
        selectedItems.filter((val) => val !== item)
      )
    }
  }

  async function search() {
    setLoading(true)
    const { hits } = await fetch(
      `https://hn.algolia.com/api/v1/search?query=${searchWord}`
    ).then((response) => response.json())

    setItems(hits.slice(0, 8))
    setLoading(false)
  }

  return (
    <>
      <Modal width={850} visible={true} closable={false} footer={[]}>
        <Input.Search
          value={searchWord}
          onChange={(e) => {
            setSearchWord(e.target.value)
          }}
          onSearch={search}
        />
        <Divider />
        <Table
          loading={loading}
          rowKey={(record) => record.objectID}
          columns={initColumns}
          dataSource={items}
        />
        <Divider />
        <Button onClick={() => console.log(selectedItems)}>
          Print Selected Items
        </Button>
      </Modal>
    </>
  )
}

export default App

这段代码的功能是“显示一些表格行,并选择/选择所有这些行”。 在此处输入图像描述

到目前为止,它工作正常。但是由于某种原因,我必须使columnsofTable有状态。所以我改变了代码:

  ...
  // On some situation I have to change the columns, for example change the columns' width.
  const [columns, setColumns] = useState(initColumns) 
  ... 
  <Table
    loading={loading}
    rowKey={(record) => record.objectID}
    columns={columns}
    dataSource={items}
  />
  ...

更改完成后,select/selectAll 将不起作用!我认为这可能与 React 的更新/刷新逻辑有关。

所以我尝试添加这些:

  // On some situation I have to change the columns, for example change the columns' width.
  const [columns, setColumns] = useState(initColumns) 

  useEffect(() => {
    setColumns(initColumns)
  }, [items, selectedItems])

该代码现在工作正常。但我还是不明白为什么!我已经使用 React 2 个月了,但我无法自己找出这个问题。

如果有人能告诉我这里到底发生了什么,我将不胜感激!

(我尽量把自己说清楚,但是我的英语不够好。如果你不完全理解我的写作,请给我留言!)

标签: javascriptreactjsfrontend

解决方案


推荐阅读