Skip to content

Commit 12694f3

Browse files
yongningfufuyongning
and
fuyongning
authored
perf: nested Trigger should not force render when ancestor Trigger render (#270)
Change-Id: I1cbe580d44011aeecbe8337ed18d3f8239a6d402 Co-authored-by: fuyongning <fuyongning@bytedance.com>
1 parent 57a21f2 commit 12694f3

File tree

2 files changed

+66
-10
lines changed

2 files changed

+66
-10
lines changed

src/index.tsx

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -780,15 +780,12 @@ export function generateTrigger(
780780
this.setPopupVisible(false);
781781
}
782782

783+
triggerContextValue = { onPopupMouseDown: this.onPopupMouseDown };
784+
783785
render() {
784786
const { popupVisible } = this.state;
785-
const {
786-
children,
787-
forceRender,
788-
alignPoint,
789-
className,
790-
autoDestroy,
791-
} = this.props;
787+
const { children, forceRender, alignPoint, className, autoDestroy } =
788+
this.props;
792789
const child = React.Children.only(children) as React.ReactElement;
793790
const newChildProps: HTMLAttributes<HTMLElement> & { key: string } = {
794791
key: 'trigger',
@@ -877,9 +874,7 @@ export function generateTrigger(
877874
}
878875

879876
return (
880-
<TriggerContext.Provider
881-
value={{ onPopupMouseDown: this.onPopupMouseDown }}
882-
>
877+
<TriggerContext.Provider value={this.triggerContextValue}>
883878
{trigger}
884879
{portal}
885880
</TriggerContext.Provider>

tests/basic.test.jsx

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,4 +749,65 @@ describe('Trigger.Basic', () => {
749749
document.body.removeChild(div);
750750
document.body.removeChild(root);
751751
});
752+
753+
it('nested Trigger should not force render when ancestor Trigger render', () => {
754+
let isUpdate = false;
755+
let isChildUpdate = false;
756+
let isGrandsonUpdate = false;
757+
758+
const Grandson = () => {
759+
if (isUpdate) {
760+
isGrandsonUpdate = true;
761+
}
762+
763+
return null;
764+
};
765+
766+
const Child = React.memo(() => {
767+
if (isUpdate) {
768+
isChildUpdate = true;
769+
}
770+
771+
return (
772+
<Trigger
773+
action={['click']}
774+
popupAlign={placementAlignMap.left}
775+
forceRender
776+
popup={() => (
777+
<strong className="x-content">
778+
<Grandson />
779+
</strong>
780+
)}
781+
>
782+
<div className="target">click</div>
783+
</Trigger>
784+
);
785+
});
786+
787+
class App extends React.Component {
788+
render() {
789+
return (
790+
<Trigger
791+
action={['click']}
792+
popupAlign={placementAlignMap.left}
793+
popup={<strong className="x-content">tooltip2</strong>}
794+
className="className-in-trigger-2"
795+
>
796+
<div className="target">
797+
<Child />
798+
</div>
799+
</Trigger>
800+
);
801+
}
802+
}
803+
804+
const wrapper = mount(<App />);
805+
806+
isUpdate = true;
807+
808+
wrapper.setState({});
809+
810+
expect(isChildUpdate).toBeFalsy();
811+
expect(isGrandsonUpdate).toBeFalsy();
812+
});
752813
});

0 commit comments

Comments
 (0)