You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React表单调用heavyCalculation慢函数导致输入卡顿 不修改慢函数如何优化

问题根因

  • 每次修改任意输入框时,App组件的form状态更新触发整体重渲染,所有6个Input组件都会跟着重渲染
  • 每个Input组件重渲染时都会无差别执行一次heavyCalculation慢函数,6次叠加导致输入卡顿
  • 未对handleChange做引用缓存,未对Input做渲染阻断,导致大量无必要的重渲染

解决方案

不需要修改heavyCalculation本身,按以下两步调整即可:

  1. 用React.memo包裹Input组件,只有当Input的props发生变化时才触发重渲染;同时用useMemo缓存heavyCalculation的执行,无依赖的情况下只会在组件挂载时执行1次
  2. 用useCallback缓存App中的handleChange函数,同时改成函数式更新form状态,避免依赖外层form变量导致引用频繁变化

修改后的App.js代码

import React, { useState, useCallback } from "react";
import Input from "components/Input";
import Button from "components/Button";
import { Card } from "antd";
import "antd/dist/antd.css";
import * as S from "./style";

const App = () => {
    const [form, setForm] = useState({ userName: "", email: "", password: "", firstName: "", lastName: "", city: "" });

    // 用useCallback缓存引用,函数式更新不需要依赖外层form
    const handleChange = useCallback((fieldName, value) => {
        setForm(prevForm => ({
            ...prevForm,
            [fieldName]: value
        }));
    }, []);

    const handleSubmit = () => {
        console.log(form);
    };

    return (
        <S.Content>
            <Card title={"Sign Up"} bordered={false} style={{ width: 500, height: 450 }}>
                <S.Form>
                    <Input value={form.userName} fieldName="userName" onChange={handleChange} placeholder="Username" />
                    <Input value={form.email} fieldName="email" onChange={handleChange} placeholder="Email" />
                    <Input value={form.password} fieldName="password" type="password" onChange={handleChange} placeholder="Password" />
                    <Input value={form.firstName} fieldName="firstName" onChange={handleChange} placeholder="First Name" />
                    <Input value={form.lastName} fieldName="lastName" onChange={handleChange} placeholder="Last Name" />
                    <Input value={form.city} fieldName="city" onChange={handleChange} placeholder="City" />
                    <Button onClick={handleSubmit} label="Submit" />
                </S.Form>
            </Card>
        </S.Content>
    );
};

export default App;

修改后的Input组件代码

import React, { useMemo } from "react";
import { heavyCalculation } from "global";
import * as Antd from "antd";

// 用React.memo包裹,仅props变化时重渲染
const Input = React.memo(({ fieldName, value, onChange, placeholder }) => {
    // 无依赖的useMemo,仅组件挂载时执行一次heavyCalculation
    useMemo(() => {
        heavyCalculation();
    }, []);

    const handleChange = (e) => {
        onChange(fieldName, e.target.value);
    };

    return <Antd.Input value={value} onChange={handleChange} placeholder={placeholder} />;
});

export default Input;

如果实际业务中heavyCalculation需要依赖某个变量,只需要把对应的变量加到useMemo的依赖数组中,就只会在依赖变化时重新执行,不会每次重渲染都运行。

内容的提问来源于stack exchange,提问作者Mickael Zana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 16:27:04