import React, { useState } from 'react';
import AccountLogin from './component/AccountLogin.jsx'
import SmCodeLogin from './component/SmCodeLogin.jsx'
import { Form, Input, Button, Row, Col } from 'antd';
import IconMap from 'components/IconMap.jsx';
import logoImg from 'common/img/logo.png';
import './css/login.less';
const FormItem = Form.Item;
const Login = () => {
const [form] = Form.useForm();
const [type, setType] = useState('account');
console.log(form,'form');
const submitUserInfo = (values) => {
console.log(values);
}
const ComponentSelector = props => type==='account' ? <AccountLogin {...props} /> : <SmCodeLogin {...props} />;
return (
<div className="form-wrapper">
<div className="logo">
<img src={logoImg} alt="logo" />
<span>人事管理系统</span>
</div>
<Form form={form} onFinish={submitUserInfo}>
{ComponentSelector({form, FormItem, Input})}
<Row>
<Button block={true} type="primary" htmlType="submit">登录</Button>
</Row>
<Row className="txt-tip">
<Col span={6}>忘记密码</Col>
<Col span={18} className="txt-right" onClick={() => setType(type!=='account' ? 'account' : 'smcode')}>
{
type!=='account' ? '使用账户名密码进行登录' : '使用手机号进行登录'
}
{IconMap.arrRowRight}
</Col>
</Row>
</Form>
</div>
);
};
export default Login;
1、为什么不用 useEffect?
你这段是JSX 条件渲染,处在组件渲染执行流程里:
- 组件任意 state /props 更新 → 函数组件重新执行;
type是useState变量,调用setType修改后,组件重渲染;- 三元表达式重新判断
type === 'account'; - 要么返回
<AccountLogin>,要么返回<SmCodeLogin>,DOM 自动替换。
示例完整代码:
jsx
const [type, setType] = useState('account');
const ComponentSelector = props => {
return type === 'account'
? <AccountLogin {...props} />
: <SmCodeLogin {...props} />;
};
// 使用
<ComponentSelector />
setType('code') 执行后立刻换组件,完全不需要手动监听 type。
2、两个细节关键点
(1)组件会卸载重建,内部状态会清空
AccountLogin 和 SmCodeLogin 是两个完全不同组件:
- 切换时旧组件执行
useEffect(()=>()=>{})卸载逻辑; - 新组件全新挂载,内部
useState、输入框内容都会重置。
如果你希望切换类型保留表单输入内容,就不能直接替换组件,要用显示 / 隐藏(display:none)而非条件卸载。
(2)什么时候才真的需要 useEffect?
只有下面这类场景才要监听 type:
- type 变化时,发接口请求;
- type 变化时重置外层 form 表单;
- type 变化操作 DOM、执行异步逻辑。
示例:
jsx
useEffect(() => {
// 类型切换,清空表单
form.resetFields();
}, [type]);
只是单纯切换渲染哪个组件,完全没必要。




