performance enhancements and render reductions

This commit is contained in:
James
2020-07-23 17:40:16 -04:00
parent 846589e303
commit d2055141be
3 changed files with 195 additions and 99 deletions

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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);