检查和存储哪些状态已从初始值改变的简单方法

Simple approach to check and store which states that has changed from initial value

此组件检查字段是否已从初始值更改并显示更改的字段数。每个字段都有一个 useEffect。用更干的东西会更好,但还没有弄清楚如何。

有没有办法更快更好地做到这一点?

    const [unsavedChanges, setUnsavedChanges] = useState<Array<string>>([]);
    const [customField1, setCustomField1] = useState<string | null | undefined>(
        Data.field1
    );
    const [customField2, setCustomField2] = useState<string | null | undefined>(
        Data.field2
    );

设置未保存的更改状态

//Field 1
    useEffect(() => {
        if (
            (customField1 === Data.field1 ||
                customField1 === null) &&
            unsavedChanges?.includes('customfield1')
        ) {
            let filtered = unsavedChanges.filter(
                (item) => item !== 'customfield1'
            );
            setUnsavedChanges(filtered);
        } else if (
            customField1 === Data.field1 ||
            unsavedChanges?.includes('customfield1')
        ) {
            return;
        } else {
            setUnsavedChanges([...unsavedChanges, 'customfield1']);
        }
    }, [customField1]);

//Field 2
    useEffect(() => {
        if (
            (customField2 === Data.field2 ||
                customField2 === null) &&
            unsavedChanges?.includes('customfield2')
        ) {
            let filtered = unsavedChanges.filter(
                (item) => item !== 'customfield2'
            );
            setUnsavedChanges(filtered);
        } else if (
            customField2 === Data.field2 ||
            unsavedChanges?.includes('customfield2')
        ) {
            return;
        } else {
            setUnsavedChanges([...unsavedChanges, 'customfield2']);
        }
    }, [customField2]);

Return

        <>
            <Input value={customField1} onChange={setCustomField1(e.target.value}/>
            <Input value={customField2} onChange={setCustomField2(e.target.value}/>
            <h1>{unsavedChanges.length} # of unsaved changes.</h1>
            <Button disabled={unsavedChanges.length > 0 ? false : true} label='Submit'/>
        </>

我创建了一个如何使其变得简单的示例(在我看来)。 我将三个状态合并为一个。这样我就可以以更动态的方式获得每一个。然后我创建了一个更改处理程序来处理更改并执行所有 if 语句(使用更少的代码)。 每个输入都在更改时触发更改处理程序。并根据 if 语句设置状态。 这样我们就可以创建任意多的输入,我们只需要将正确的参数传递给更改处理程序,它会为我们处理剩下的事情(并确保向状态包含更多的键值对)

这是数据的虚拟数据:

 const Data = { field1: "abc", field2: "efg" };

状态:

  const [generalState, setGeneralState] = useState({
     unsavedChanges: [],
     customField1: "",
     customField2: ""
  });

处理程序:

const changeTheState = (type, value, field, customField) => {
    //setting the values to the state. so we can fetch the values for the inputs and for later use
    setGeneralState((prev) => ({ ...prev, [type]: value }));

    // i narrowed down the if statements. now its only two.
    if (
      value === Data[field] &&
      generalState.unsavedChanges?.includes(customField)
    ) {
      return setGeneralState((prev) => {
        let filtered = prev.unsavedChanges.filter(
          (item) => item !== customField
        );
        return { ...prev, unsavedChanges: filtered };
      });
    }

    if (!generalState.unsavedChanges?.includes(customField)) {
      setGeneralState((prev) => ({
        ...prev,
        unsavedChanges: [...prev.unsavedChanges, customField]
      }));
    }
  };

和 jsx:

<div className="App">
      <input
        value={generalState.customField1}
        onChange={(e) => {
          changeTheState(
            "customField1",
            e.target.value,
            "field1",
            "customField1"
          );
        }}
      />
      <input
        value={generalState.customField2}
        onChange={(e) => {
          changeTheState(
            "customField2",
            e.target.value,
            "field2",
            "customField2"
          );
        }}
      />

      <h1>{generalState.unsavedChanges.length} # of unsaved changes.</h1>
      <button disabled={generalState.unsavedChanges.length > 0 ? false : true}>
        Submit
      </button>
    </div>

示例如下:codesandbox example

您可以做的另一件事是为输入创建一个可重用的组件。创建对象数组来表示每个输入。遍历数组并生成任意数量的输入。

如果您需要额外的解释,请告诉我。