mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2025-04-06 21:40:23 +08:00
Merge pull request #547 from smartxworks/fix/deep-compare-slotContext
fix(ImplWrapper): deep compare slotContext in memo
This commit is contained in:
commit
706898a91e
@ -1,6 +1,7 @@
|
||||
import '@testing-library/jest-dom/extend-expect';
|
||||
import { render, screen, waitFor, act } from '@testing-library/react';
|
||||
import produce from 'immer';
|
||||
import React from 'react';
|
||||
import { initSunmaoUI } from '../../src';
|
||||
import { TestLib } from '../testLib';
|
||||
import { destroyTimesMap, renderTimesMap, clearTesterMap } from '../testLib/Tester';
|
||||
@ -11,6 +12,7 @@ import {
|
||||
MergeStateSchema,
|
||||
AsyncMergeStateSchema,
|
||||
TabsWithSlotsSchema,
|
||||
ParentRerenderSchema,
|
||||
} from './mockSchema';
|
||||
|
||||
// A pure single sunmao component will render twice when it mount.
|
||||
@ -68,6 +70,28 @@ describe('hidden trait condition', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when parent rerender change', () => {
|
||||
it('the children should not rerender', () => {
|
||||
const { App, stateManager, apiService } = initSunmaoUI({ libs: [TestLib] });
|
||||
stateManager.noConsoleError = true;
|
||||
const { unmount } = render(<App options={ParentRerenderSchema} />);
|
||||
const childTester = screen.getByTestId('tester');
|
||||
expect(childTester).toHaveTextContent(SingleComponentRenderTimes);
|
||||
act(() => {
|
||||
apiService.send('uiMethod', {
|
||||
componentId: 'input',
|
||||
name: 'setValue',
|
||||
parameters: 'foo',
|
||||
});
|
||||
});
|
||||
expect(childTester).toHaveTextContent(SingleComponentRenderTimes);
|
||||
expect(stateManager.store['input'].value).toBe('foo');
|
||||
|
||||
unmount();
|
||||
clearTesterMap();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when component merge state synchronously', () => {
|
||||
it('it will not cause extra render', () => {
|
||||
const { App, stateManager } = initSunmaoUI({ libs: [TestLib] });
|
||||
|
@ -84,6 +84,55 @@ export const HiddenTraitSchema: Application = {
|
||||
},
|
||||
};
|
||||
|
||||
export const ParentRerenderSchema: Application = {
|
||||
version: 'sunmao/v1',
|
||||
kind: 'Application',
|
||||
metadata: {
|
||||
name: 'some App',
|
||||
},
|
||||
spec: {
|
||||
components: [
|
||||
{
|
||||
id: 'input',
|
||||
type: 'test/v1/input',
|
||||
properties: {
|
||||
defaultValue: '',
|
||||
},
|
||||
traits: [],
|
||||
},
|
||||
{
|
||||
id: 'stack6',
|
||||
type: 'core/v1/stack',
|
||||
properties: {
|
||||
spacing: 12,
|
||||
direction: 'horizontal',
|
||||
align: 'auto',
|
||||
wrap: '{{!!input.value}}',
|
||||
justify: 'flex-start',
|
||||
},
|
||||
traits: [],
|
||||
},
|
||||
{
|
||||
id: 'tester',
|
||||
type: 'test/v1/tester',
|
||||
properties: {},
|
||||
traits: [
|
||||
{
|
||||
type: 'core/v1/slot',
|
||||
properties: {
|
||||
container: {
|
||||
id: 'stack6',
|
||||
slot: 'content',
|
||||
},
|
||||
ifCondition: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export const MergeStateSchema: Application = {
|
||||
version: 'sunmao/v1',
|
||||
kind: 'Application',
|
||||
|
@ -2,6 +2,7 @@ import React from 'react';
|
||||
import { ImplWrapperProps } from '../../../types';
|
||||
import { shallowCompare } from '@sunmao-ui/shared';
|
||||
import { UnmountImplWrapper } from './UnmountImplWrapper';
|
||||
import { isEqual } from 'lodash';
|
||||
|
||||
export const ImplWrapper = React.memo<ImplWrapperProps>(
|
||||
UnmountImplWrapper,
|
||||
@ -10,20 +11,19 @@ export const ImplWrapper = React.memo<ImplWrapperProps>(
|
||||
const nextChildren = nextProps.childrenMap[nextProps.component.id]?._grandChildren;
|
||||
const prevComponent = prevProps.component;
|
||||
const nextComponent = nextProps.component;
|
||||
let isEqual = false;
|
||||
let isComponentEqual = false;
|
||||
|
||||
if (prevChildren && nextChildren) {
|
||||
isEqual = shallowCompare(prevChildren, nextChildren);
|
||||
isComponentEqual = shallowCompare(prevChildren, nextChildren);
|
||||
} else if (prevChildren === nextChildren) {
|
||||
isEqual = true;
|
||||
isComponentEqual = true;
|
||||
}
|
||||
|
||||
return (
|
||||
isEqual &&
|
||||
isComponentEqual &&
|
||||
prevComponent === nextComponent &&
|
||||
// TODO: keep ImplWrapper memorized and get slot props from store
|
||||
shallowCompare(prevProps.slotProps, nextProps.slotProps) &&
|
||||
shallowCompare(prevProps.slotContext, nextProps.slotContext)
|
||||
isEqual(prevProps.slotContext, nextProps.slotContext)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user