#javascript #reactjs #frontend
Вопрос:
По какой-то причине я должен сделать опору «столбцы» компонента таблицы с сохранением состояния. Затем происходит какая-то неожиданная ошибка.
Следующий код работает нормально, как и ожидалось:
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: lt;a onClick={selectAll}gt;Select Alllt;/agt;, render: (_, record) =gt; ( lt;Checkbox checked={selectedItems.includes(record)} onChange={(e) =gt; select(e.target.checked, record)} /gt; ), 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) =gt; selectedItems.concat([item])) } else { setSelectedItems((selectedItems) =gt; selectedItems.filter((val) =gt; val !== item) ) } } async function search() { setLoading(true) const { hits } = await fetch( `https://hn.algolia.com/api/v1/search?query=${searchWord}` ).then((response) =gt; response.json()) setItems(hits.slice(0, 8)) setLoading(false) } return ( lt;gt; lt;Modal width={850} visible={true} closable={false} footer={[]}gt; lt;Input.Search value={searchWord} onChange={(e) =gt; { setSearchWord(e.target.value) }} onSearch={search} /gt; lt;Divider /gt; lt;Table loading={loading} rowKey={(record) =gt; record.objectID} columns={initColumns} dataSource={items} /gt; lt;Divider /gt; lt;Button onClick={() =gt; console.log(selectedItems)}gt; Print Selected Items lt;/Buttongt; lt;/Modalgt; lt;/gt; ) } export default App
Функциональность этого фрагмента кода заключается в том, чтобы «отобразить некоторые строки таблицы и выбрать/выбрать все эти строки».
Until now it works fine. However for some reason I have to make the columns
of Table
stateful. So I change the code:
... // On some situation I have to change the columns, for example change the columns' width. const [columns, setColumns] = useState(initColumns) ... lt;Table loading={loading} rowKey={(record) =gt; record.objectID} columns={columns} dataSource={items} /gt; ...
When the change is done, the select/selectAll just won’t work! I thought it might be related to React’s update/refresh logic.
So I tried to add these:
// On some situation I have to change the columns, for example change the columns' width. const [columns, setColumns] = useState(initColumns) useEffect(() =gt; { setColumns(initColumns) }, [items, selectedItems])
The code works fine now. But I still don’t understand why! I’ve been using React for like 2 months now, and I can’t find out this problem on my own.
I would really appreciate if some one can tell me what happened exactly here!
(I tried to make myself clear as I can, but my English is not good enough. If you don’t fully understand my writing, please leave me a message!)