#javascript #reactjs #use-state
#javascript #reactjs #use-state
Вопрос:
У меня есть выпадающий список, который появляется при нажатии кнопки внутри таблицы react.
function Table({ columns, data, getTrProps, isShowing }) {
const [isVisible, setIsVisible] = useState(false);
const currentColOrder = React.useRef();
const { store } = useContext(AppContext);
const handleChange = () => {
setIsVisible(() => !isVisible);
};
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
allColumns,
visibleColumns,
setColumnOrder,
getToggleHideAllColumnsProps,
} = useTable(
{
columns,
data,
},
useSortBy,
useRowSelect,
useColumnOrder,
hooks => {
hooks.visibleColumns.push(columns => [
{
id: 'selection',
className: 'selection',
disableSortBy: true,
accessor: '',
Header: ({ getToggleAllRowsSelectedProps }) => (
<div>
<IndeterminateCheckbox {...getToggleAllRowsSelectedProps()} />
</div>
),
Cell: ({ row }) => (
<div>
<IndeterminateCheckbox {...row.getToggleRowSelectedProps()} />
</div>
),
},
...columns,
{
className: 'Columns_Menu',
disableSortBy: true,
id: 'Eye',
Header: () => (
<StyledEyeButton type="button" onClick={handleChange} id="eye">
<Eye />
</StyledEyeButton>
),
Cell: () => <div />,
},
]);
},
);
return (
<>
<StyledTable {...getTableProps()} isShowing={isShowing}>
<thead>
{headerGroups.map(headerGroup => (
<DragDropContext
onDragStart={() => {
currentColOrder.current = visibleColumns.map(o => o.id);
}}
onDragUpdate={dragUpdateObj => {
const colOrder = [...currentColOrder.current];
const sIndex = dragUpdateObj.source.index;
const dIndex = dragUpdateObj.destination amp;amp; dragUpdateObj.destination.index;
if (typeof sIndex === 'number' amp;amp; typeof dIndex === 'number') {
colOrder.splice(sIndex, 1);
colOrder.splice(dIndex, 0, dragUpdateObj.draggableId);
setColumnOrder(colOrder);
}
}}
key={1}
>
<Droppable droppableId="droppable" direction="horizontal">
{droppableProvided => (
<tr {...headerGroup.getHeaderGroupProps()} ref={droppableProvided.innerRef}>
{headerGroup.headers.map((column, index) => (
<Draggable
key={column.id}
draggableId={column.id}
index={index}
isDragDisabled={!column.accessor}
>
{(provided, snapshot) => {
return (
<StyledTh {...column.getHeaderProps(column.getSortByToggleProps())}>
<div {...column.getHeaderProps()}>
<div
{...provided.draggableProps}
{...provided.dragHandleProps}
ref={provided.innerRef}
style={{
...getItemStyle(snapshot, provided.draggableProps.style),
}}
>
<StyledHeader className="header">
{column.render('Header')}
{column.id === 'selection' || column.id === 'Eye' ? (
''
) : column.isSorted ? (
column.isSortedDesc ? (
<UpChevron />
) : (
<DownChevron />
)
) : (
<DownChevron />
)}
</StyledHeader>
</div>
</div>
</StyledTh>
);
}}
</Draggable>
))}
</tr>
)}
</Droppable>
</DragDropContext>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map(row => {
prepareRow(row);
return (
<StyledTr {...row.getRowProps()} data-testid="row">
{store?.get?.isLoadingSearchButton || store?.get?.isLoadingApplyButton
? row.cells.map(cell => {
return (
<StyledTd
{...cell.getCellProps()}
{...getTrProps(cell)}
className={cell.column.className}
>
<Skeleton width="50%" />
</StyledTd>
);
})
: row.cells.map(cell => {
return (
<StyledTd
{...cell.getCellProps()}
{...getTrProps(cell)}
className={cell.column.className}
>
{cell.render('Cell')}
</StyledTd>
);
})}
</StyledTr>
);
})}
</tbody>
</StyledTable>
{isVisible ? (
<DropDownTableMenu
setIsVisible={setIsVisible}
allColumns={allColumns}
getToggleHideAllColumnsProps={getToggleHideAllColumnsProps}
isVisible={isVisible}
/>
) : (
<></>
)}
</>
);
}
Изначально значение isVisible
равно false. Когда я нажимаю на StyledEyeButton
выпадающий список, он открывается, как и должен, и isVisible
значение изменяется на true.
Однако, когда я снова нажимаю на кнопку, чтобы закрыть выпадающий список, значение для isVisible
переключается на false, а затем переключается во второй раз обратно на true, так что выпадающий список никогда не закрывается.
У меня есть функция on outside click, которая передается в выпадающий список в таблице, и когда вы нажимаете вне выпадающего списка, она закрывается нормально, но проблема возникает только тогда, когда вы пытаетесь нажать кнопку eye, чтобы закрыть выпадающий список после открытия.
Я думал, что использование анонимной функции в handleChange
должно было решить проблему, но это не так. Есть идеи, что является причиной этого? Единственное, о чем я могу думать, это то, что сама кнопка визуализируется из функции, и это вызывает проблему с состоянием, но я не был уверен, потому что кнопка не должна повторно визуализироваться после начальной загрузки.
Комментарии:
1. Не могли бы вы поделиться своим полным кодом? В настоящее время я не могу найти никакого использования isVisible в вашем коде.
2. Да, есть целая функция таблицы, раскрывающийся список show находится внизу функции @fi
3. Вероятно, проблема вызвана внешним щелчком. Когда вы нажимаете на выпадающий список, он запускает оба — выпадающий щелчок и внешний щелчок. Вы можете решить эту проблему, используя этот
stopPropagation
метод.4. Я попытался удалить компонент OutsideClickHandler, который оборачивает выпадающий компонент, и это тоже не исправило его @yochanansheinberger
5. как выглядит ваш внешний щелчок? Я думаю, что проблема заключается в вашем внешнем клике