繁体   English   中英

如何避免反应 forms 中的数据重复

[英]How to avoid data duplication in react forms

在不使用任何库的情况下,我很难在 React 中获得一个简洁的代码来做一个简单的表单。

假设我有

import React, { useState } from 'react';

export const CreateUserForm = () => {
  const [firstName, setFirstName] = useState('');

  const userAddress = {};

  const handleAddressChange = ({ address, isValid }) => {
    userAddress = { ...address };
  };

  const subscribe = () => {
    createUser({firstName, userAddress}).then((response) => console.log(response));
  };

  return (
    <div>
      <input onChange={setFirstName}></input>
      <AddressForm onChange={handleAddressChange}></AddressForm>
      <button onClick={subscribe}></button>
    </div>
  );
};

在这里,我复制了CreateUserForm组件中的addressaddressAddressForm状态下进行管理)。

我可以向AddressForm组件添加一些props ,所以我最终会得到类似的东西:

import React, { useState } from 'react';

export const CreateUserForm = () => {
  const [firstName, setFirstName] = useState('');
  const [address, setAddress] = useState({});

  const handleAddressChange = ({ address, isValid }) => {
    setAddress({ ...address });
  };

  const subscribe = () => {
    createUser({firstName, userAddress}).then((response) => console.log(response));
  };

  return (
    <div>
      <input onChange={setFirstName}></input>
      <AddressForm address={address} onChange={handleAddressChange}></AddressForm>
      <button onClick={subscribe}></button>
    </div>
  );
};

所以在这里我不会复制address ,但每次地址更改时我都会渲染整个CreateUserForm组件,我错了吗?

所以我觉得这些解决方案都不是很好,还是我错过了什么? 第一个对我来说似乎更自然,但我有点重复信息..

正确的方法是什么?

第二个选项是正确的选项,因为第一个选项可能不起作用,如果它起作用,那么如果您使 CreateUserForm 组件更复杂,就会有一些错误等待显示出来。

选项 1 没有正确使用 state 并且很容易搞砸,因为 userAddress 不是有状态的。 每次重新渲染组件时,它都会重置为 {}。 为了使第一个选项起作用,您需要 useRef 来设置您的地址变量。

import React, { useState, useRef } from 'react';

export const CreateUserForm = () => {
  const [firstName, setFirstName] = useState('');

  const userAddress = useRef({});

  const handleAddressChange = ({ address, isValid }) => {
    userAddress.current = { ...address };
  };

  const subscribe = () => {
    createUser({firstName, userAddress: userAddress.current}).then((response) => console.log(response));
  };

  return (
    <div>
      <input onChange={setFirstName}></input>
      <AddressForm onChange={handleAddressChange}></AddressForm>
      <button onClick={subscribe}></button>
    </div>
  );
};

对第一个选项的这种更改将防止重新渲染,但代价是使 AddressForm 控制得更少。 它还会阻止您将地址传递给组件的任何其他子级,因为它们不会重新渲染,因为除非您更改名字输入,否则父级也不会重新渲染。

每次在第二个选项中调用 handleAddressChange 时,CreateUserForm 组件肯定会重新渲染。 通常在较小的应用程序中,重新渲染不会有性能问题。 如果您开始遇到性能问题,请找出 CreateUserForm 的哪些子项需要一段时间来重新渲染和记忆它们(React.Memo 或 PureComponent),这样组件将快速重新渲染。 尽管 memoization 还要求您确保传递给组件的内容在引用上是稳定的(即 useCallback 和 useRef)。

我通常检查表单是否渲染得足够快的方法是按住表单输入上的一个键,看看它是否以非生涩的方式重复。 尽管该特定指标主要来自我的理想,并且并非所有应用程序都完全必要。

我知道您试图在没有表单库的情况下工作,但是react-hook-form似乎能够根据目的提供从完全不受控制到受控的范围,以保持性能并最大限度地减少过多的重新渲染。

第二种方法更好,因为您不必在两个组件(父组件和子组件)中维护数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM