如何重构React组件中expandCols函数内的if/else if代码块?
如何重构并精简React组件中的expandCols函数?
我想重构并精简React组件里的expandCols函数,特别是map方法里的if/else if代码块,但暂时没思路。这个函数在用户触发“展开列”时执行,组件会接收包含列头及列相关数据的props。
原函数代码
const expandCols = () => { const grid = [ { id: 1, data: 1, name: 'col1', visible: true, foreignKey: null }, { id: 2, data: 12, name: 'test', visible: true, foreignKey: 'vis' }, { id: 3, data: 13, name: 'test', visible: true, foreignKey: 'vis' }, { id: 4, data: 14, name: 'test', visible: true, foreignKey: 'vis' }, { id: 5, data: 15, name: 'not test', visible: true, foreignKey: 'not vis' }, { id: 6, data: 16, name: 'not test', visible: true, foreignKey: 'not vis' }, { id: 7, data: 17, name: 'random 1', visible: true, foreignKey: 'N/A' }, { id: 8, data: 18, name: 'random 2', visible: true, foreignKey: 'N/A' }, { id: 9, data: 19, name: 'dynamic visible col', visible: true, foreignKey: 'make me visible' }, { id: 10, data: 20, name: 'dynamic visible col', visible: true, foreignKey: 'make me visible' }, { id: 11, data: 21, name: 'dynamic visible col', visible: true, foreignKey: 'make me visible' }, { id: 12, data: 22, name: 'dynamic visible col', visible: true, foreignKey: 'make me visible' }, ]; //value from props passed in from parent can be: 'test', 'not test', or 'dynamic visible col' const headerVals = props.headerVals let isExpanded = true; grid.map((column) => { if (column.name === 'test' && column.foreignKey === 'yup') { isExpanded = !column.visible; return (column.visible = !column.visible); } else if (column.name === 'not test' && column.foreignKey === 'not yup') { isExpanded = !column.visible; return (column.visible = !column.visible); } else if (column.name === 'dynamic visible col' && column.foreignKey === 'make me visible') { isExpanded = !column.visible; return (column.visible = !column.visible); } }); if (isExpanded) { if (headerVals === 'test') { // show test column in grid // functionality to accomplish this is used with another library } else if (headerVals === 'not test') { // show not test column in grid // functionality to accomplish this is used with another library } else if (headerVals === 'dynamic visible col') { // show dynamic visible col in grid // functionality to accomplish this is used with another library } } else { if (headerVals === 'test') { // hide test column in grid // functionality to accomplish this is used with another library } else if (headerVals === 'not test') { // hide not test column in grid // functionality to accomplish this is used with another library } else if (headerVals === 'dynamic visible col') { // hide dynamic visible col in grid // functionality to accomplish this is used with another library } } }
重构方案
核心优化思路
- 用配置映射表替代冗余的if/else判断,把列名与对应foreignKey的关联规则抽离,后续新增列规则只需修改映射表,无需改动逻辑代码。
- 用
forEach替代map遍历修改数组(map语义上是生成新数组,不适合直接修改原数据)。 - 合并显示/隐藏的逻辑分支,减少重复代码块,提升可读性。
重构后的代码
// 抽离列规则映射,统一管理列名与foreignKey的对应关系 const COLUMN_RULES = { 'test': 'yup', 'not test': 'not yup', 'dynamic visible col': 'make me visible' }; const expandCols = () => { const grid = [ { id: 1, data: 1, name: 'col1', visible: true, foreignKey: null }, { id: 2, data: 12, name: 'test', visible: true, foreignKey: 'vis' }, { id: 3, data: 13, name: 'test', visible: true, foreignKey: 'vis' }, { id: 4, data: 14, name: 'test', visible: true, foreignKey: 'vis' }, { id: 5, data: 15, name: 'not test', visible: true, foreignKey: 'not vis' }, { id: 6, data: 16, name: 'not test', visible: true, foreignKey: 'not vis' }, { id: 7, data: 17, name: 'random 1', visible: true, foreignKey: 'N/A' }, { id: 8, data: 18, name: 'random 2', visible: true, foreignKey: 'N/A' }, { id: 9, data: 19, name: 'dynamic visible col', visible: true, foreignKey: 'make me visible' }, { id: 10, data: 20, name: 'dynamic visible col', visible: true, foreignKey: 'make me visible' }, { id: 11, data: 21, name: 'dynamic visible col', visible: true, foreignKey: 'make me visible' }, { id: 12, data: 22, name: 'dynamic visible col', visible: true, foreignKey: 'make me visible' }, ]; const headerVals = props.headerVals; let isExpanded = true; // 用forEach遍历修改原数组,语义更贴合修改操作 grid.forEach(column => { const expectedForeignKey = COLUMN_RULES[column.name]; if (expectedForeignKey && column.foreignKey === expectedForeignKey) { column.visible = !column.visible; isExpanded = column.visible; // 直接取更新后的可见状态,逻辑更清晰 } }); // 合并显示/隐藏逻辑,用switch替代嵌套if/else,减少重复代码 const action = isExpanded ? 'show' : 'hide'; switch (headerVals) { case 'test': // 调用第三方库逻辑:${action} test column in grid break; case 'not test': // 调用第三方库逻辑:${action} not test column in grid break; case 'dynamic visible col': // 调用第三方库逻辑:${action} dynamic visible col in grid break; } };
额外优化建议(遵循React数据不可变性)
如果需要遵循React数据不可变原则,避免直接修改原数组,可以改用map生成新数组:
const COLUMN_RULES = { 'test': 'yup', 'not test': 'not yup', 'dynamic visible col': 'make me visible' }; const expandCols = () => { const originalGrid = [/* 原grid数据 */]; const headerVals = props.headerVals; // 生成新数组,不修改原数据,符合React不可变数据规范 const updatedGrid = originalGrid.map(column => { const expectedForeignKey = COLUMN_RULES[column.name]; if (expectedForeignKey && column.foreignKey === expectedForeignKey) { return { ...column, visible: !column.visible }; } return column; }); // 获取目标列的可见状态 const targetColumn = updatedGrid.find(col => { const key = COLUMN_RULES[col.name]; return key && col.foreignKey === key; }); const isExpanded = targetColumn ? targetColumn.visible : true; // 后续显示/隐藏逻辑同上 const action = isExpanded ? 'show' : 'hide'; switch (headerVals) { case 'test': // 调用第三方库逻辑 break; // ...其他case } // 如果需要更新组件状态,把updatedGrid存入state // setGrid(updatedGrid); };
内容的提问来源于stack exchange,提问作者new_coder
相关产品推荐
相关产品推荐

