mirror of
https://github.com/nowcommunity/nowdatabase.git
synced 2026-10-12 19:13:52 +03:00
factor out unnecessary temporary array
This commit is contained in:
@@ -49,11 +49,11 @@ The context can also be used to access, for example, the **setEditData** setter,
|
||||
|
||||
**editingComponents**
|
||||
|
||||
If an editingComponent has an error, the `field` value of the component is added to the `allErrors` array in the context. editingComponents have a useEffect hook that runs every time their `error` value changes which either adds or removes them from the `allErrors` array. This array is used to make sure all fields have a proper value before allowing the user to add a new entry (the "Finalize Entry" button is disabled if `allErrors` has anything in it).
|
||||
If an editingComponent has an error, the `field` value of the component is added to the `fieldsWithErrors` array in the context. editingComponents have a useEffect hook that runs every time their `error` value changes which either adds or removes them from the `fieldsWithErrors` array. This array is used to make sure all fields have a proper value before allowing the user to add a new entry (the "Finalize Entry" button is disabled if `fieldsWithErrors` has anything in it).
|
||||
|
||||
Instead of calling the `setAllErrors` function directly with the new array of errors, editingComponents pass an updater function to it.
|
||||
Instead of calling the `setFieldsWithErrors` function directly with the new array of errors, editingComponents pass an updater function to it.
|
||||
|
||||

|
||||

|
||||
|
||||
This ensures that when multiple components try to update the state at the same time, they don't overwrite each other. The react documentation goes into more detail: https://react.dev/reference/react/useState#updating-state-based-on-the-previous-state
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
@@ -69,8 +69,8 @@ export type DetailContextType<T> = {
|
||||
optionalRadioSelectionProps?: OptionalRadioSelectionProps
|
||||
) => JSX.Element
|
||||
validator: (editData: EditDataType<T>, field: keyof EditDataType<T>) => ValidationObject
|
||||
allErrors: Array<string>
|
||||
setAllErrors: (updaterFn: (prevErrors: Array<string>) => Array<string>) => void
|
||||
fieldsWithErrors: Array<string>
|
||||
setFieldsWithErrors: (updaterFn: (prevErrors: Array<string>) => Array<string>) => void
|
||||
}
|
||||
|
||||
export const DetailContext = createContext<DetailContextType<unknown>>(null!)
|
||||
|
||||
@@ -73,7 +73,7 @@ export const DetailView = <T extends object>({
|
||||
}
|
||||
const { editRights } = usePageContext()
|
||||
const [mode, setModeState] = useState<ModeType>(isNew ? modeOptionToMode['new'] : modeOptionToMode['read'])
|
||||
const [allErrors, setAllErrors] = useState<Array<string>>([])
|
||||
const [fieldsWithErrors, setFieldsWithErrors] = useState<Array<string>>([])
|
||||
const [tab, setTab] = useState(getUrl())
|
||||
|
||||
useEffect(() => {
|
||||
@@ -125,21 +125,18 @@ export const DetailView = <T extends object>({
|
||||
radioSelection,
|
||||
bigTextField,
|
||||
validator,
|
||||
allErrors,
|
||||
setAllErrors,
|
||||
fieldsWithErrors,
|
||||
setFieldsWithErrors,
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (mode.option === 'edit' || mode.option === 'new') {
|
||||
const validationErrors: Array<string> = []
|
||||
for (const field in initialState.editData) {
|
||||
// if (field === 'references') continue
|
||||
const { error } = validator(initialState.editData, field)
|
||||
if (error) {
|
||||
validationErrors.push(field)
|
||||
setFieldsWithErrors(fieldsWithErrors => fieldsWithErrors.concat(field))
|
||||
}
|
||||
}
|
||||
setAllErrors(validationErrors)
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [mode])
|
||||
|
||||
@@ -51,19 +51,19 @@ export const DropdownSelector = <T extends object>({
|
||||
field: keyof EditDataType<T>
|
||||
disabled?: boolean
|
||||
}) => {
|
||||
const { setEditData, editData, validator, allErrors, setAllErrors } = useDetailContext<T>()
|
||||
const { setEditData, editData, validator, fieldsWithErrors, setFieldsWithErrors } = useDetailContext<T>()
|
||||
const { error } = validator(editData, field)
|
||||
|
||||
useEffect(() => {
|
||||
const errorField = String(field)
|
||||
if (error && !allErrors.includes(errorField)) {
|
||||
if (error && !fieldsWithErrors.includes(errorField)) {
|
||||
// saves invalid field into array of errors in context
|
||||
setAllErrors(prevErrors => {
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return [...prevErrors, errorField]
|
||||
})
|
||||
} else if (!error && allErrors.includes(errorField)) {
|
||||
} else if (!error && fieldsWithErrors.includes(errorField)) {
|
||||
// removes valid field from the array
|
||||
setAllErrors(prevErrors => {
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return prevErrors.filter(err => err !== errorField)
|
||||
})
|
||||
}
|
||||
@@ -227,20 +227,20 @@ export const EditableTextField = <T extends object>({
|
||||
readonly?: boolean
|
||||
handleSetEditData?: (value: number | string) => void
|
||||
}) => {
|
||||
const { setEditData, editData, validator, allErrors, setAllErrors } = useDetailContext<T>()
|
||||
const { setEditData, editData, validator, fieldsWithErrors, setFieldsWithErrors } = useDetailContext<T>()
|
||||
const { error } = validator(editData, field)
|
||||
const name = String(field)
|
||||
|
||||
useEffect(() => {
|
||||
const errorField = String(field)
|
||||
if (error && !allErrors.includes(errorField)) {
|
||||
if (error && !fieldsWithErrors.includes(errorField)) {
|
||||
// saves invalid field into array of errors in context
|
||||
setAllErrors(prevErrors => {
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return [...prevErrors, errorField]
|
||||
})
|
||||
} else if (!error && allErrors.includes(errorField)) {
|
||||
} else if (!error && fieldsWithErrors.includes(errorField)) {
|
||||
// removes valid field from the array
|
||||
setAllErrors(prevErrors => {
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return prevErrors.filter(err => err !== errorField)
|
||||
})
|
||||
}
|
||||
@@ -294,7 +294,7 @@ export const FieldWithTableSelection = <T extends object, ParentType extends obj
|
||||
selectorTable: ReactElement
|
||||
disabled?: boolean
|
||||
}) => {
|
||||
const { editData, setEditData, validator, allErrors, setAllErrors } = useDetailContext<ParentType>()
|
||||
const { editData, setEditData, validator, fieldsWithErrors, setFieldsWithErrors } = useDetailContext<ParentType>()
|
||||
const { error } = validator(editData, targetField as keyof EditDataType<ParentType>)
|
||||
const [open, setOpen] = useState(false)
|
||||
const selectorFn = (selected: T) => {
|
||||
@@ -304,14 +304,14 @@ export const FieldWithTableSelection = <T extends object, ParentType extends obj
|
||||
|
||||
useEffect(() => {
|
||||
const errorField = String(targetField)
|
||||
if (error && !allErrors.includes(errorField)) {
|
||||
if (error && !fieldsWithErrors.includes(errorField)) {
|
||||
// saves invalid field into array of errors in context
|
||||
setAllErrors(prevErrors => {
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return [...prevErrors, errorField]
|
||||
})
|
||||
} else if (!error && allErrors.includes(errorField)) {
|
||||
} else if (!error && fieldsWithErrors.includes(errorField)) {
|
||||
// removes valid field from the array
|
||||
setAllErrors(prevErrors => {
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return prevErrors.filter(err => err !== errorField)
|
||||
})
|
||||
}
|
||||
@@ -363,7 +363,7 @@ export const TimeBoundSelection = <T extends object, ParentType extends object>(
|
||||
selectorTable: ReactElement
|
||||
disabled?: boolean
|
||||
}) => {
|
||||
const { editData, setEditData, validator, allErrors, setAllErrors } = useDetailContext<ParentType>()
|
||||
const { editData, setEditData, validator, fieldsWithErrors, setFieldsWithErrors } = useDetailContext<ParentType>()
|
||||
const { error: boundError } = validator(
|
||||
editData,
|
||||
(targetField === 'up_bnd' ? 'up_bound' : 'low_bound') as keyof EditDataType<ParentType>
|
||||
@@ -381,14 +381,14 @@ export const TimeBoundSelection = <T extends object, ParentType extends object>(
|
||||
|
||||
useEffect(() => {
|
||||
const errorField = String(targetField)
|
||||
if (boundError && !allErrors.includes(errorField)) {
|
||||
if (boundError && !fieldsWithErrors.includes(errorField)) {
|
||||
// saves invalid field into array of errors in context
|
||||
setAllErrors(prevErrors => {
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return [...prevErrors, errorField]
|
||||
})
|
||||
} else if (!boundError && allErrors.includes(errorField)) {
|
||||
} else if (!boundError && fieldsWithErrors.includes(errorField)) {
|
||||
// removes valid field from the array
|
||||
setAllErrors(prevErrors => {
|
||||
setFieldsWithErrors(prevErrors => {
|
||||
return prevErrors.filter(err => err !== errorField)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export const WriteButton = <T,>({
|
||||
onWrite: (editData: EditDataType<T>, setEditData: (editData: EditDataType<T>) => void) => Promise<void>
|
||||
hasStagingMode?: boolean
|
||||
}) => {
|
||||
const { editData, setEditData, mode, setMode, allErrors } = useDetailContext<T>()
|
||||
const { editData, setEditData, mode, setMode, fieldsWithErrors } = useDetailContext<T>()
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
const getButtonText = () => {
|
||||
@@ -24,7 +24,7 @@ export const WriteButton = <T,>({
|
||||
|
||||
return (
|
||||
<Button
|
||||
disabled={allErrors.length > 0}
|
||||
disabled={fieldsWithErrors.length > 0}
|
||||
id="write-button"
|
||||
sx={{ width: '20em' }}
|
||||
onClick={() => {
|
||||
|
||||
Reference in New Issue
Block a user