performance enhancements and render reductions
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { createContext, useContext } from 'react';
|
||||
import React, { createContext, useEffect, useContext, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import RenderCustomComponent from '../../utilities/RenderCustomComponent';
|
||||
|
||||
@@ -22,12 +22,24 @@ const RenderFields = (props) => {
|
||||
|
||||
const { customComponentsPath: customComponentsPathFromContext, operation: operationFromContext } = useRenderedFields();
|
||||
|
||||
const customComponentsPath = customComponentsPathFromProps || customComponentsPathFromContext;
|
||||
const operation = operationFromProps || operationFromContext;
|
||||
const customComponentsPath = customComponentsPathFromProps || customComponentsPathFromContext;
|
||||
|
||||
const [contextValue, setContextValue] = useState({
|
||||
operation,
|
||||
customComponentsPath,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setContextValue({
|
||||
operation,
|
||||
customComponentsPath,
|
||||
});
|
||||
}, [operation, customComponentsPath]);
|
||||
|
||||
if (fieldSchema) {
|
||||
return (
|
||||
<RenderedFieldContext.Provider value={{ customComponentsPath, operation }}>
|
||||
<RenderedFieldContext.Provider value={contextValue}>
|
||||
{fieldSchema.map((field, i) => {
|
||||
if (!field?.hidden && field?.admin?.disabled !== true) {
|
||||
if ((filter && typeof filter === 'function' && filter(field)) || !filter) {
|
||||
|
||||
@@ -62,7 +62,7 @@ const ArrayFieldType = (props) => {
|
||||
required,
|
||||
});
|
||||
|
||||
const addRow = (rowIndex) => {
|
||||
const addRow = useCallback((rowIndex) => {
|
||||
const data = getDataByPath(path);
|
||||
|
||||
dispatchRows({
|
||||
@@ -70,9 +70,9 @@ const ArrayFieldType = (props) => {
|
||||
});
|
||||
|
||||
setValue(value + 1);
|
||||
};
|
||||
}, [dispatchRows, getDataByPath, path, setValue, value]);
|
||||
|
||||
const removeRow = (rowIndex) => {
|
||||
const removeRow = useCallback((rowIndex) => {
|
||||
const data = getDataByPath(path);
|
||||
|
||||
dispatchRows({
|
||||
@@ -82,22 +82,22 @@ const ArrayFieldType = (props) => {
|
||||
});
|
||||
|
||||
setValue(value - 1);
|
||||
};
|
||||
}, [dispatchRows, path, getDataByPath, setValue, value]);
|
||||
|
||||
const moveRow = (moveFromIndex, moveToIndex) => {
|
||||
const moveRow = useCallback((moveFromIndex, moveToIndex) => {
|
||||
const data = getDataByPath(path);
|
||||
|
||||
dispatchRows({
|
||||
type: 'MOVE', index: moveFromIndex, moveToIndex, data,
|
||||
});
|
||||
};
|
||||
}, [dispatchRows, getDataByPath, path]);
|
||||
|
||||
const onDragEnd = (result) => {
|
||||
const onDragEnd = useCallback((result) => {
|
||||
if (!result.destination) return;
|
||||
const sourceIndex = result.source.index;
|
||||
const destinationIndex = result.destination.index;
|
||||
moveRow(sourceIndex, destinationIndex);
|
||||
};
|
||||
}, [moveRow]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatchRows({
|
||||
@@ -123,6 +123,84 @@ const ArrayFieldType = (props) => {
|
||||
}
|
||||
}, [value, setValue, disableFormData, dataToInitialize]);
|
||||
|
||||
return (
|
||||
<RenderArray
|
||||
onDragEnd={onDragEnd}
|
||||
label={label}
|
||||
showError={showError}
|
||||
errorMessage={errorMessage}
|
||||
rows={rows}
|
||||
singularLabel={singularLabel}
|
||||
addRow={addRow}
|
||||
removeRow={removeRow}
|
||||
moveRow={moveRow}
|
||||
path={path}
|
||||
customComponentsPath={customComponentsPath}
|
||||
name={name}
|
||||
fieldTypes={fieldTypes}
|
||||
fields={fields}
|
||||
permissions={permissions}
|
||||
value={value}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
ArrayFieldType.defaultProps = {
|
||||
label: '',
|
||||
defaultValue: [],
|
||||
initialData: [],
|
||||
validate: array,
|
||||
required: false,
|
||||
maxRows: undefined,
|
||||
minRows: undefined,
|
||||
singularLabel: 'Row',
|
||||
permissions: {},
|
||||
};
|
||||
|
||||
ArrayFieldType.propTypes = {
|
||||
defaultValue: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
),
|
||||
initialData: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
),
|
||||
fields: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
).isRequired,
|
||||
label: PropTypes.string,
|
||||
singularLabel: PropTypes.string,
|
||||
name: PropTypes.string.isRequired,
|
||||
path: PropTypes.string.isRequired,
|
||||
fieldTypes: PropTypes.shape({}).isRequired,
|
||||
validate: PropTypes.func,
|
||||
required: PropTypes.bool,
|
||||
maxRows: PropTypes.number,
|
||||
minRows: PropTypes.number,
|
||||
permissions: PropTypes.shape({
|
||||
fields: PropTypes.shape({}),
|
||||
}),
|
||||
};
|
||||
|
||||
const RenderArray = React.memo((props) => {
|
||||
const {
|
||||
onDragEnd,
|
||||
label,
|
||||
showError,
|
||||
errorMessage,
|
||||
rows,
|
||||
singularLabel,
|
||||
addRow,
|
||||
removeRow,
|
||||
moveRow,
|
||||
path,
|
||||
customComponentsPath,
|
||||
name,
|
||||
fieldTypes,
|
||||
fields,
|
||||
permissions,
|
||||
value,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<DragDropContext onDragEnd={onDragEnd}>
|
||||
<div className={baseClass}>
|
||||
@@ -179,42 +257,6 @@ const ArrayFieldType = (props) => {
|
||||
</div>
|
||||
</DragDropContext>
|
||||
);
|
||||
};
|
||||
|
||||
ArrayFieldType.defaultProps = {
|
||||
label: '',
|
||||
defaultValue: [],
|
||||
initialData: [],
|
||||
validate: array,
|
||||
required: false,
|
||||
maxRows: undefined,
|
||||
minRows: undefined,
|
||||
singularLabel: 'Row',
|
||||
permissions: {},
|
||||
};
|
||||
|
||||
ArrayFieldType.propTypes = {
|
||||
defaultValue: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
),
|
||||
initialData: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
),
|
||||
fields: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
).isRequired,
|
||||
label: PropTypes.string,
|
||||
singularLabel: PropTypes.string,
|
||||
name: PropTypes.string.isRequired,
|
||||
path: PropTypes.string.isRequired,
|
||||
fieldTypes: PropTypes.shape({}).isRequired,
|
||||
validate: PropTypes.func,
|
||||
required: PropTypes.bool,
|
||||
maxRows: PropTypes.number,
|
||||
minRows: PropTypes.number,
|
||||
permissions: PropTypes.shape({
|
||||
fields: PropTypes.shape({}),
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
export default withCondition(ArrayFieldType);
|
||||
|
||||
@@ -15,7 +15,7 @@ import Error from '../../Error';
|
||||
import useFieldType from '../../useFieldType';
|
||||
import Popup from '../../../elements/Popup';
|
||||
import BlockSelector from './BlockSelector';
|
||||
import { blocks } from '../../../../../fields/validations';
|
||||
import { blocks as blocksValidator } from '../../../../../fields/validations';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
@@ -71,7 +71,7 @@ const Blocks = (props) => {
|
||||
const { customComponentsPath } = useRenderedFields();
|
||||
const { getDataByPath } = useForm();
|
||||
|
||||
const addRow = (index, blockType) => {
|
||||
const addRow = useCallback((index, blockType) => {
|
||||
const data = getDataByPath(path);
|
||||
|
||||
dispatchRows({
|
||||
@@ -79,9 +79,9 @@ const Blocks = (props) => {
|
||||
});
|
||||
|
||||
setValue(value + 1);
|
||||
};
|
||||
}, [getDataByPath, path, setValue, value]);
|
||||
|
||||
const removeRow = (index) => {
|
||||
const removeRow = useCallback((index) => {
|
||||
const data = getDataByPath(path);
|
||||
|
||||
dispatchRows({
|
||||
@@ -91,28 +91,28 @@ const Blocks = (props) => {
|
||||
});
|
||||
|
||||
setValue(value - 1);
|
||||
};
|
||||
}, [getDataByPath, path, setValue, value]);
|
||||
|
||||
const moveRow = (moveFromIndex, moveToIndex) => {
|
||||
const moveRow = useCallback((moveFromIndex, moveToIndex) => {
|
||||
const data = getDataByPath(path);
|
||||
|
||||
dispatchRows({
|
||||
type: 'MOVE', index: moveFromIndex, moveToIndex, data,
|
||||
});
|
||||
};
|
||||
}, [getDataByPath, path]);
|
||||
|
||||
const toggleCollapse = (index) => {
|
||||
const toggleCollapse = useCallback((index) => {
|
||||
dispatchRows({
|
||||
type: 'TOGGLE_COLLAPSE', index, rows,
|
||||
});
|
||||
};
|
||||
}, [rows]);
|
||||
|
||||
const onDragEnd = (result) => {
|
||||
const onDragEnd = useCallback((result) => {
|
||||
if (!result.destination) return;
|
||||
const sourceIndex = result.source.index;
|
||||
const destinationIndex = result.destination.index;
|
||||
moveRow(sourceIndex, destinationIndex);
|
||||
};
|
||||
}, [moveRow]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatchRows({
|
||||
@@ -138,6 +138,87 @@ const Blocks = (props) => {
|
||||
}
|
||||
}, [value, setValue, disableFormData, dataToInitialize]);
|
||||
|
||||
return (
|
||||
<RenderBlock
|
||||
onDragEnd={onDragEnd}
|
||||
label={label}
|
||||
showError={showError}
|
||||
errorMessage={errorMessage}
|
||||
rows={rows}
|
||||
singularLabel={singularLabel}
|
||||
addRow={addRow}
|
||||
removeRow={removeRow}
|
||||
moveRow={moveRow}
|
||||
path={path}
|
||||
customComponentsPath={customComponentsPath}
|
||||
name={name}
|
||||
fieldTypes={fieldTypes}
|
||||
toggleCollapse={toggleCollapse}
|
||||
permissions={permissions}
|
||||
value={value}
|
||||
dataToInitialize={dataToInitialize}
|
||||
blocks={blocks}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
Blocks.defaultProps = {
|
||||
label: '',
|
||||
defaultValue: [],
|
||||
initialData: [],
|
||||
singularLabel: 'Block',
|
||||
validate: blocksValidator,
|
||||
required: false,
|
||||
maxRows: undefined,
|
||||
minRows: undefined,
|
||||
permissions: {},
|
||||
};
|
||||
|
||||
Blocks.propTypes = {
|
||||
blocks: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
).isRequired,
|
||||
defaultValue: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
),
|
||||
initialData: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
),
|
||||
label: PropTypes.string,
|
||||
singularLabel: PropTypes.string,
|
||||
name: PropTypes.string.isRequired,
|
||||
path: PropTypes.string.isRequired,
|
||||
fieldTypes: PropTypes.shape({}).isRequired,
|
||||
validate: PropTypes.func,
|
||||
required: PropTypes.bool,
|
||||
maxRows: PropTypes.number,
|
||||
minRows: PropTypes.number,
|
||||
permissions: PropTypes.shape({
|
||||
fields: PropTypes.shape({}),
|
||||
}),
|
||||
};
|
||||
|
||||
const RenderBlock = React.memo((props) => {
|
||||
const {
|
||||
onDragEnd,
|
||||
label,
|
||||
showError,
|
||||
errorMessage,
|
||||
rows,
|
||||
singularLabel,
|
||||
addRow,
|
||||
removeRow,
|
||||
moveRow,
|
||||
path,
|
||||
customComponentsPath,
|
||||
name,
|
||||
fieldTypes,
|
||||
permissions,
|
||||
value,
|
||||
toggleCollapse,
|
||||
dataToInitialize,
|
||||
blocks,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<DragDropContext onDragEnd={onDragEnd}>
|
||||
@@ -235,45 +316,6 @@ const Blocks = (props) => {
|
||||
</div>
|
||||
</DragDropContext>
|
||||
);
|
||||
};
|
||||
|
||||
Blocks.defaultProps = {
|
||||
label: '',
|
||||
defaultValue: [],
|
||||
initialData: [],
|
||||
singularLabel: 'Block',
|
||||
validate: blocks,
|
||||
required: false,
|
||||
maxRows: undefined,
|
||||
minRows: undefined,
|
||||
permissions: {},
|
||||
};
|
||||
|
||||
Blocks.propTypes = {
|
||||
blocks: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
).isRequired,
|
||||
defaultValue: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
),
|
||||
initialData: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
),
|
||||
blocks: PropTypes.arrayOf(
|
||||
PropTypes.shape({}),
|
||||
).isRequired,
|
||||
label: PropTypes.string,
|
||||
singularLabel: PropTypes.string,
|
||||
name: PropTypes.string.isRequired,
|
||||
path: PropTypes.string.isRequired,
|
||||
fieldTypes: PropTypes.shape({}).isRequired,
|
||||
validate: PropTypes.func,
|
||||
required: PropTypes.bool,
|
||||
maxRows: PropTypes.number,
|
||||
minRows: PropTypes.number,
|
||||
permissions: PropTypes.shape({
|
||||
fields: PropTypes.shape({}),
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
export default withCondition(Blocks);
|
||||
|
||||
Reference in New Issue
Block a user