diff --git a/src/components/Fields/Field.tsx b/src/components/Fields/Field.tsx index 3f18b225..c2f03a17 100644 --- a/src/components/Fields/Field.tsx +++ b/src/components/Fields/Field.tsx @@ -29,7 +29,7 @@ export interface FieldProps extends SchemaOptions { } @observer -export class Field extends React.Component { +export class Field extends React.PureComponent { toggle = () => { if (this.props.field.expanded === undefined && this.props.expandByDefault) { this.props.field.expanded = false; diff --git a/src/components/Schema/ObjectSchema.tsx b/src/components/Schema/ObjectSchema.tsx index 66f6034a..9b526981 100644 --- a/src/components/Schema/ObjectSchema.tsx +++ b/src/components/Schema/ObjectSchema.tsx @@ -18,37 +18,35 @@ export interface ObjectSchemaProps extends SchemaProps { }; } -@observer -export class ObjectSchema extends React.Component { - static contextType = OptionsContext; +export const ObjectSchemaComponent = observer( + ({ + schema: { fields = [], title }, + showTitle, + discriminator, + skipReadOnly, + skipWriteOnly, + }: ObjectSchemaProps) => { + const { expandSingleSchemaField, showObjectExample } = React.useContext(OptionsContext); - get parentSchema() { - return this.props.discriminator!.parentSchema; - } + const filteredFields = React.useMemo( + () => + skipReadOnly || skipWriteOnly + ? fields.filter( + item => + !( + (skipReadOnly && item.schema.readOnly) || + (skipWriteOnly && item.schema.writeOnly) + ), + ) + : fields, + [skipReadOnly, skipWriteOnly, fields], + ); - render() { - const { - schema: { fields = [] }, - showTitle, - discriminator, - } = this.props; - - const needFilter = this.props.skipReadOnly || this.props.skipWriteOnly; - - const filteredFields = needFilter - ? fields.filter(item => { - return !( - (this.props.skipReadOnly && item.schema.readOnly) || - (this.props.skipWriteOnly && item.schema.writeOnly) - ); - }) - : fields; - - const expandByDefault = this.context.expandSingleSchemaField && filteredFields.length === 1; + const expandByDefault = expandSingleSchemaField && filteredFields.length === 1; return ( - {showTitle && {this.props.schema.title}} + {showTitle && {title}} {mapWithLast(filteredFields, (field, isLast) => { return ( @@ -58,26 +56,27 @@ export class ObjectSchema extends React.Component { field={field} expandByDefault={expandByDefault} renderDiscriminatorSwitch={ - (discriminator && - discriminator.fieldName === field.name && - (() => ( - - ))) || - undefined + discriminator?.fieldName === field.name + ? () => ( + + ) + : undefined } className={field.expanded ? 'expanded' : undefined} - showExamples={false} - skipReadOnly={this.props.skipReadOnly} - skipWriteOnly={this.props.skipWriteOnly} - showTitle={this.props.showTitle} + showExamples={showObjectExample} + skipReadOnly={skipReadOnly} + skipWriteOnly={skipWriteOnly} + showTitle={showTitle} /> ); })} ); - } -} + }, +); + +export const ObjectSchema = React.memo(ObjectSchemaComponent); diff --git a/src/components/__tests__/DiscriminatorDropdown.test.tsx b/src/components/__tests__/DiscriminatorDropdown.test.tsx index 6c02d1c6..25a90b27 100644 --- a/src/components/__tests__/DiscriminatorDropdown.test.tsx +++ b/src/components/__tests__/DiscriminatorDropdown.test.tsx @@ -7,7 +7,7 @@ import * as React from 'react'; import { filterPropsDeep } from '../../utils/test-utils'; -import { ObjectSchema, Schema } from '../'; +import { ObjectSchemaComponent, ObjectSchema, Schema } from '../'; import { OpenAPIParser, SchemaModel } from '../../services'; import { RedocNormalizedOptions } from '../../services/RedocNormalizedOptions'; import * as simpleDiscriminatorFixture from './fixtures/simple-discriminator.json'; @@ -26,7 +26,7 @@ describe('Components', () => { options, ); const schemaViewElement = shallow().getElement(); - expect(schemaViewElement.type).toEqual(ObjectSchema); + expect(schemaViewElement.type).toEqual(ObjectSchemaComponent); expect(schemaViewElement.props.discriminator).toBeDefined(); expect(schemaViewElement.props.discriminator.parentSchema).toBeDefined(); expect(schemaViewElement.props.discriminator.fieldName).toEqual('type'); diff --git a/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap b/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap index 7af7b482..4db31764 100644 --- a/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap +++ b/src/components/__tests__/__snapshots__/DiscriminatorDropdown.test.tsx.snap @@ -4,6 +4,7 @@ exports[`Components SchemaView discriminator should correctly render discriminat