【发布时间】:2021-12-03 03:04:47
【问题描述】:
我正在开发一个可重复使用的过滤器组件,该组件在下拉列表中动态创建一个复选框列表,并包括一个“全部选中”切换(类似于谷歌航班)。一切都按预期工作,但是单击复选框时会有很大的延迟,尤其是在使用全选切换时。它与here 描述的问题非常相似(甚至几乎相同),但我已尽力实施其中描述的解决方案,但无济于事。我尝试在所有传递的函数上应用 useCallback,并摆脱了“你为什么渲染”的所有警告,但都没有解决问题。我希望这里有人可以帮助告诉我我缺少什么。请参阅下面的相关代码 sn-ps。谢谢!
这是管理数据的父组件:
import React, { useState, useEffect } from "react";
import ControlPanel from '../Components/ControlPanel';
const TopLevelComponent = () => {
const [data, setData] = useState();
const [selectedFilters, setSelectedFilters] = useState([]);
useEffect(() => {
getData();
}, [])
const getData = async() => {
...
}
return (
<div>
<ControlPanel
filterOptions={ data?.filterSet }
filterSelections={ selectedFilters }
filterHandler={ setSelectedFilters }
/>
{ /* other stuff irrelevant here */ }
</div>
)
}
export default TopLevelComponent;
这是一个可重复使用的控制面板组件,其中包含过滤器和其他设置:
import React from "react";
import { Filter } from './Inputs';
const ControlPanel = ({ filterOptions, filterSelections, filterHandler }) => {
return (
<>
{ /* other controls not relevant here */ }
<div className="control-panel__filters">
<Filter
filterName="Filter A"
options={ filterOptions }
handler={ filterHandler }
selections={ filterSelections }
selectAllLabel="Select all filter A"
/>
</div>
{ /* more irrelevant stuff */ }
</>
)
}
export default ControlPanel;
最后,这是定义过滤器和组成它们的组件的地方:
import React, { useState } from "react";
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem, Label } from 'reactstrap';
import Toggle from 'react-toggle';
import chevronDown from '../icons/chevron-down-dark.svg';
import chevronUp from '../icons/chevron-top.svg';
import closeIcon from '../icons/close.svg';
export const Filter = ({ options, handler, selections, filterName, selectAllLabel }) => {
const [dropdownOpen, setDropdownOpen] = useState(false);
const toggle = () => setDropdownOpen(prevState => !prevState);
return (
<Dropdown isOpen={ dropdownOpen } toggle={ toggle } >
<DropdownToggle>
{ filterName }
<img src={ dropdownOpen ? chevronUp : chevronDown } />
</DropdownToggle>
<DropdownMenu>
<FilterInterface
toggle={ toggle }
filterName={ filterName }
options={ options }
selections={ selections }
handler={ handler }
selectAllLabel={ selectAllLabel }
/>
</DropdownMenu>
</Dropdown>
);
}
const FilterInterface = ({ toggle, filterName, options, selections, handler, selectAllLabel }) => {
const [allSelected, setAllSelected] = useState(false);
const toggleAllSelected = () => {
if (options.length !== selections.length) {
const newSelections = options.map(option => option.id);
handler(newSelections);
setAllSelected(true);
} else {
handler([]);
setAllSelected(false);
}
}
const handleCheck = id => {
let newArray;
if (selections.includes(id)) {
newArray = selections.filter(selection => {
return selection !== id;
});
setAllSelected(false);
} else {
newArray = [...selections, id];
}
handler(newArray);
if (newArray.length === options.length) setAllSelected(true);
}
return (
<>
<DropdownItem header>
{ filterName }
<img src={ closeIcon } onClick={ toggle } />
</DropdownItem>
<DropdownItem header>
{selectAllLabel}
<Toggle
checked={ allSelected }
icons={ false }
onChange={ toggleAllSelected }
/>
</DropdownItem>
{
options?.map(option => (
<DropdownItem header
key={ option.id }
value={ option.name }
className="filterCheckbox"
>
<Label onClick={ () => handleCheck(option.id) }>
<Checkbox checked={ selections.includes(option.id) } readOnly />
<span>{ option.name }</span>
</Label>
</DropdownItem>
))
}
</>
)
}
【问题讨论】:
标签: javascript reactjs performance latency