簡體   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