React Table默认过滤状态 Toggle开关控制显示Good数据实现
实现方案
直接改3处就能实现需求,顺便修复了原代码里matchData多余左括号的语法错误:
- 新增状态变量控制「显示Good状态菜单」开关,默认值为
false,也就是默认关闭、不展示Good状态数据 - 调整
matchData过滤逻辑:开关关闭时过滤掉status === "Good"的数据,开关开启时返回全量数据,同时保留原有的手动隐藏行过滤规则 - 在Apply按钮旁插入已封装的Toggle组件,绑定对应状态和修改方法,配上开关文字说明
修改后完整代码
export default function MenuDisplay() { const { menuId } = useParams(); const [selected, setSelected] = useState({}); const [hidden, setHidden] = useState({}); const [menus, setMenus] = useState([]); // 新增:控制Good状态菜单显示的开关状态,默认关闭 const [showGoodMenus, setShowGoodMenus] = useState(false); useEffect(() => { axios.post(url,{menuId:parseInt(menuId)}) .then(res => { console.log(res) setMenus(res.data.menus) }) .catch(err => { console.log(err) }) }, [menuId]); // 选中任意行时按钮为Apply状态,否则为Cancel状态 const buttonMode = Object.values(selected).some((isSelected) => isSelected) ? "apply" : "cancel"; const rowSelectHandler = (id) => (checked) => { setSelected((selected) => ({ ...selected, [id]: checked })); }; const handleClick = () => { if (buttonMode === "apply") { // 隐藏当前选中项 const currentlySelected = {}; Object.entries(selected).forEach(([id, isSelected]) => { if (isSelected) { currentlySelected[id] = isSelected; } }); setHidden({ ...hidden, ...currentlySelected }); // 清空所有选中状态 const newSelected = {}; Object.keys(selected).forEach((id) => { newSelected[id] = false; }); setSelected(newSelected); } else { // 选中所有当前隐藏项 const currentlyHidden = {}; Object.entries(hidden).forEach(([id, isHidden]) => { if (isHidden) { currentlyHidden[id] = isHidden; } }); setSelected({ ...selected, ...currentlyHidden }); // 清空所有隐藏项 const newHidden = {}; Object.keys(hidden).forEach((id) => { newHidden[id] = false; }); setHidden(newHidden); } }; // 修正原语法错误,新增状态过滤逻辑 const matchData = menus.filter(({ _id, status }) => { // 先过滤被手动隐藏的行 if (hidden[_id]) return false; // 开关关闭时,过滤掉Good状态的数据 if (!showGoodMenus && status === "Good") return false; return true; }); const getRowProps = (row) => { return { style: { backgroundColor: selected[row.values.id] ? "lightgrey" : "white" } }; }; const columns = [ { Header: "id", accessor: (row) => row._id }, { Header: "Name", accessor: (row) => ( <Link to={{ pathname: `/menu/${menuId}/${row._id}` }}>{row.name}</Link> ) }, { Header: "Description", accessor: (row) => row.description }, { Header: "Status", accessor: (row) => row.status }, { Header: "Dishes", accessor: (row) => row.dishes, id: "dishes", Cell: ({ value }) => value && Object.values(value[0]).join(", ") }, { Header: "Show", accessor: (row) => ( <Toggle value={selected[row._id]} onChange={rowSelectHandler(row._id)} /> ) } ]; const initialState = { sortBy: [ { desc: false, id: "id" }, { desc: false, id: "description" } ], hiddenColumns: ["dishes", "id"] }; return ( <div> <button type="button" onClick={handleClick}> {buttonMode === "cancel" ? "Cancel" : "Apply"} </button> {/* 新增:Show good menus开关 */} <label style={{ marginLeft: "12px", display: "inline-flex", alignItems: "center", gap: "6px", cursor: "pointer" }}> <Toggle value={showGoodMenus} onChange={(checked) => setShowGoodMenus(checked)} /> <span>Show good menus</span> </label> <Table data={matchData} columns={columns} initialState={initialState} withCellBorder withRowBorder withSorting withPagination rowProps={getRowProps} /> </div> ); }
逻辑说明
- 默认状态下表格仅展示
Pending和Not started的条目,符合初始需求 - 开关开启时自动解除对
Good状态的过滤,展示全量数据,开关关闭后立刻恢复默认过滤规则 - 原有手动选择隐藏/显示行的逻辑和状态过滤完全独立,互不影响
- 用label标签包裹开关和文字,点击文字也能触发开关切换,符合常规交互习惯
内容的提问来源于stack exchange,提问作者Zokulko
相关产品推荐
相关产品推荐

