如何将4个自定义登录组件按上次登录方式置顶排序?
问题解答
你的思路完全可行
将组件存入带标识的数组后排序的方案逻辑清晰、易维护,具体实现步骤如下:
- 定义带标识的组件数组:
const loginComponents = [ { key: strings.tickets.login.email, component: <UsernameSignIn cta={hasSignedInAlready && lastSignedInMethod === strings.tickets.login.email} /> }, { key: strings.tickets.login.yourPhoneNumber, component: <PhoneSignIn cta={hasSignedInAlready && lastSignedInMethod === strings.tickets.login.yourPhoneNumber} /> }, { key: strings.tickets.login.apple, component: <AppleSignIn cta={hasSignedInAlready && lastSignedInMethod === strings.tickets.login.apple} setParentSigningIn={signingIn => setFreeze(signingIn)} /> }, { key: strings.tickets.login.google, component: <GoogleSignIn cta={hasSignedInAlready && lastSignedInMethod === strings.tickets.login.google} setParentSigningIn={signingIn => setFreeze(signingIn)} /> }, ];
- 对数组排序,将上次登录对应的组件移至首位:
const sortedLoginComponents = [...loginComponents].sort((a, b) => { if (a.key === lastSignedInMethod) return -1; if (b.key === lastSignedInMethod) return 1; return 0; // 其余组件保持原有顺序 });
- 遍历渲染排序后的组件(可插入分隔线):
{sortedLoginComponents.map(({ key, component }) => ( <React.Fragment key={key}> {component} {/* 插入分隔线组件或样式 */} </React.Fragment> ))}
更优实现方案
可以通过类型-组件映射表结合简单的数组重组来实现,代码更简洁直观,后续新增登录方式时维护成本更低:
- 创建登录标识与组件的映射表:
const loginComponentMap = { [strings.tickets.login.email]: <UsernameSignIn cta={hasSignedInAlready && lastSignedInMethod === strings.tickets.login.email} />, [strings.tickets.login.yourPhoneNumber]: <PhoneSignIn cta={hasSignedInAlready && lastSignedInMethod === strings.tickets.login.yourPhoneNumber} />, [strings.tickets.login.apple]: <AppleSignIn cta={hasSignedInAlready && lastSignedInMethod === strings.tickets.login.apple} setParentSigningIn={signingIn => setFreeze(signingIn)} />, [strings.tickets.login.google]: <GoogleSignIn cta={hasSignedInAlready && lastSignedInMethod === strings.tickets.login.google} setParentSigningIn={signingIn => setFreeze(signingIn)} />, };
- 生成排序后的组件数组:
// 获取所有登录方式的标识 const allLoginKeys = Object.keys(loginComponentMap); // 将上次登录的标识移至数组首位,其余保持原有顺序 const sortedKeys = [lastSignedInMethod, ...allLoginKeys.filter(key => key !== lastSignedInMethod)]; // 根据排序后的标识生成组件数组 const sortedLoginComponents = sortedKeys.map(key => loginComponentMap[key]);
- 渲染组件(自动添加分隔线):
{sortedLoginComponents.map((component, index) => ( <React.Fragment key={index}> {component} {/* 最后一个组件不显示分隔线 */} {index !== sortedLoginComponents.length - 1 && <div className="login-divider" />} </React.Fragment> ))}
这种方案的优势:
- 映射表结构清晰,新增登录方式仅需在映射表中添加条目,无需修改排序逻辑
- 排序逻辑为O(n)时间复杂度,比
sort方法的O(n log n)性能更优 - 代码可读性更强,逻辑一目了然
额外优化:简化lastSignedInMethod的获取逻辑
可以用对象映射替代多分支if-else,让代码更简洁:
const loginTypeToLabelMap = { apple: strings.tickets.login.apple, google: strings.tickets.login.google, phone: strings.tickets.login.yourPhoneNumber, username: strings.tickets.login.email, }; const lastSignedInMethod = loginTypeToLabelMap[ticketsState?.mjrLoginType] || strings.tickets.login.email; // 可设置默认值
内容的提问来源于stack exchange,提问作者Fclass
相关产品推荐
相关产品推荐

