检查和存储哪些状态已从初始值改变的简单方法
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
您可以做的另一件事是为输入创建一个可重用的组件。创建对象数组来表示每个输入。遍历数组并生成任意数量的输入。
如果您需要额外的解释,请告诉我。
此组件检查字段是否已从初始值更改并显示更改的字段数。每个字段都有一个 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
您可以做的另一件事是为输入创建一个可重用的组件。创建对象数组来表示每个输入。遍历数组并生成任意数量的输入。
如果您需要额外的解释,请告诉我。