React useCallback 钩子:这些handleChange 和handleSubmit 函数防止重新渲染的正确依赖项是什么?

问题描述 投票:0回答:1

我有一个不必要重新渲染的登录组件。我已经用 React.memo 包装了组件,并使用 useCallBack 钩子来防止在值没有改变的情况下在每个渲染上创建这些函数...

考虑以下因素:

我有一个通用的 FormComponent,它有一个道具:

function FormComponent({
   formType
}) { ....}

export default React.memo(FormComponent)

该道具将在我拥有的不同形式之间切换,例如登录、注册等 在我的示例中,我仅显示登录表单,我想我会将解决方案应用于其他人。

function FormComponent({
  formType
}) {

/* various setstate removed for brevity */

  const Forms = {
    Login: [LoginForm,
      () => loginSubmit(
        email,
        password,
        setEmail,
        setPassword,
        setFormError,
        setFormSuccess,
        setIsLoading,
        setResponseMessage,
        dispatch,
        router,
        user,
        mutate
      )
    ]
  };

  function handleChangeForUseCallBack(name, value) {
    setResponseMessage('');
    setPasswordFeedback('')
    setPasswordConfirmationFeedback('')
    setFormError(false);
    setFormSuccess(false);
    setEmailError(false);
    setPasswordError(false);
    setPasswordConfirmationError(false);
    setDisableButton(false);

    dispatch({ type: 'resetUserAccountIsVerified', })

    setEmailDup(false);


    if (value === '') setDisableButton(() => true)

    if (name === 'email') {
      setEmail(value);
    }

    if (name === 'password') {
      setPassword(value);
    }

    if (name === 'password_confirmation') {
      setPasswordConfirmation(value);
    }

    if (name === 'current_location') {
      setCurrentLocation(value);
    }

    if (name === 'current_destination') {
      setCurrentDestination(value);
    }

    if (name === 'interested_activities') {
      setInterestedActivitiesInput(value);
    }
  }

  const handleChange = useCallback((e) => {
    e.persist();
    const { name, value } = e.target;
    handleChangeForUseCallBack(name, value);
  }, [email, formType, password, password_confirmation, handleChangeForUseCallBack, setIsLoading]);

  function handleSubmitForUseCallBack(e, form) {
    e.preventDefault();
    setDisableButton(true);
    validateInputs(
      form,
      email,
      setEmailError,
      setEmailFeedback,
      password,
      password_confirmation,
      setPasswordConfirmationError,
      setPasswordConfirmationFeedback,
      setPasswordError,
      setPasswordFeedback,
      setFormSuccess,
      setFormError,
    );
    return preventSubmit ? false : Forms[form][1]()
  }

  const handleSubmit = useCallback((e, form) => {
    handleSubmitForUseCallBack(e, form);
  }, [email, password, password_confirmation, interestedActivities, handleSubmitForUseCallBack]);

  function LoginForm() {
    useEffect(() => {
      dispatch({ type: 'resetUserAccountIsVerified' })
    }, [id]);

    return (
      mounted && <GenericFormComponent
        handleSubmit={handleSubmit}
        formType={formType}
        formSuccess={formSuccess}
        formError={formError}
        accountNotVerified={accountNotVerified}
        email={email}
        emailError={emailError}
        emailFeedback={emailFeedback}
        handleChange={handleChange}
        password={password}
        passwordError={passwordError}
        passwordFeedback={passwordFeedback}
        disableButton={disableButton}
        buttonName="Log-in"
        isLoading={isLoading}
        setIsLoading={setIsLoading}
        responseMessage={responseMessage}
      />
    );
  }

  return Forms[formType][0]();
}

问题是handleSubmit有各种函数调用和传递的值需要传递到

useCallback
依赖项中吗?

如有任何帮助,我们将不胜感激!

javascript reactjs react-hooks
1个回答
1
投票

我不认为

useCallback
是这里的问题。一个潜在的原因可能是渲染
LoginForm
时运行的以下副作用:

useEffect(() => {
  dispatch({ type: 'resetUserAccountIsVerified' })
}, [id]);

但我可能是错的。我认为这里的明确问题是

LoginForm
是在您的
FormComponent
内部定义的。由于每次重新评估
FormComponent
(例如,从状态更改)时,它都在
FormComponent
内部定义,因此
LoginForm
将被重新初始化,因此如果它已经渲染,那么它将重新渲染。我认为在其他地方定义
LoginForm
可以解决你的问题。

© www.soinside.com 2019 - 2024. All rights reserved.