,

什么时候用useEffect

1、为什么不用 useEffect? 你这段是JSX 条件渲染,处在组件渲染执行流程里: 示例完整代码: js…

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 条件渲染,处在组件渲染执行流程里:

  1. 组件任意 state /props 更新 → 函数组件重新执行;
  2. typeuseState 变量,调用 setType 修改后,组件重渲染;
  3. 三元表达式重新判断 type === 'account'
  4. 要么返回 <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)组件会卸载重建,内部状态会清空

AccountLoginSmCodeLogin 是两个完全不同组件:

  • 切换时旧组件执行 useEffect(()=>()=>{}) 卸载逻辑;
  • 新组件全新挂载,内部 useState、输入框内容都会重置。

如果你希望切换类型保留表单输入内容,就不能直接替换组件,要用显示 / 隐藏(display:none)而非条件卸载。

(2)什么时候才真的需要 useEffect?

只有下面这类场景才要监听 type

  • type 变化时,发接口请求;
  • type 变化时重置外层 form 表单;
  • type 变化操作 DOM、执行异步逻辑。

示例:

jsx

useEffect(() => {
  // 类型切换,清空表单
  form.resetFields();
}, [type]);

只是单纯切换渲染哪个组件,完全没必要。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

About the Author

每个人都有自己得时区,在自己得时区里,一切都是准时的。

BlockSpare — News, Magazine and Blog Addons for (Gutenberg) Block Editor