main
js 133 lines 3.76 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @emails react-core
8 */
9
10 'use strict';
11
12 let React;
13 let ReactNoop;
14 let Scheduler;
15 let act;
16 let assertLog;
17
18 describe('ReactClassComponentPropResolution', () => {
19 beforeEach(() => {
20 jest.resetModules();
21
22 React = require('react');
23 ReactNoop = require('react-noop-renderer');
24 Scheduler = require('scheduler');
25 act = require('internal-test-utils').act;
26 assertLog = require('internal-test-utils').assertLog;
27 });
28
29 function Text({text}) {
30 Scheduler.log(text);
31 return text;
32 }
33
34 it('resolves ref and default props before calling lifecycle methods', async () => {
35 const root = ReactNoop.createRoot();
36
37 function getPropKeys(props) {
38 return Object.keys(props).join(', ');
39 }
40
41 class Component extends React.Component {
42 constructor(props) {
43 super(props);
44 Scheduler.log('constructor: ' + getPropKeys(props));
45 }
46 shouldComponentUpdate(props) {
47 Scheduler.log(
48 'shouldComponentUpdate (prev props): ' + getPropKeys(this.props),
49 );
50 Scheduler.log(
51 'shouldComponentUpdate (next props): ' + getPropKeys(props),
52 );
53 return true;
54 }
55 componentDidUpdate(props) {
56 Scheduler.log('componentDidUpdate (prev props): ' + getPropKeys(props));
57 Scheduler.log(
58 'componentDidUpdate (next props): ' + getPropKeys(this.props),
59 );
60 return true;
61 }
62 componentDidMount() {
63 Scheduler.log('componentDidMount: ' + getPropKeys(this.props));
64 return true;
65 }
66 UNSAFE_componentWillMount() {
67 Scheduler.log('componentWillMount: ' + getPropKeys(this.props));
68 }
69 UNSAFE_componentWillReceiveProps(nextProps) {
70 Scheduler.log(
71 'componentWillReceiveProps (prev props): ' + getPropKeys(this.props),
72 );
73 Scheduler.log(
74 'componentWillReceiveProps (next props): ' + getPropKeys(nextProps),
75 );
76 }
77 UNSAFE_componentWillUpdate(nextProps) {
78 Scheduler.log(
79 'componentWillUpdate (prev props): ' + getPropKeys(this.props),
80 );
81 Scheduler.log(
82 'componentWillUpdate (next props): ' + getPropKeys(nextProps),
83 );
84 }
85 componentWillUnmount() {
86 Scheduler.log('componentWillUnmount: ' + getPropKeys(this.props));
87 }
88 render() {
89 return <Text text={'render: ' + getPropKeys(this.props)} />;
90 }
91 }
92
93 Component.defaultProps = {
94 default: 'yo',
95 };
96
97 // `ref` should never appear as a prop. `default` always should.
98
99 // Mount
100 const ref = React.createRef();
101 await act(async () => {
102 root.render(<Component text="Yay" ref={ref} />);
103 });
104 assertLog([
105 'constructor: text, default',
106 'componentWillMount: text, default',
107 'render: text, default',
108 'componentDidMount: text, default',
109 ]);
110
111 // Update
112 await act(async () => {
113 root.render(<Component text="Yay (again)" ref={ref} />);
114 });
115 assertLog([
116 'componentWillReceiveProps (prev props): text, default',
117 'componentWillReceiveProps (next props): text, default',
118 'shouldComponentUpdate (prev props): text, default',
119 'shouldComponentUpdate (next props): text, default',
120 'componentWillUpdate (prev props): text, default',
121 'componentWillUpdate (next props): text, default',
122 'render: text, default',
123 'componentDidUpdate (prev props): text, default',
124 'componentDidUpdate (next props): text, default',
125 ]);
126
127 // Unmount
128 await act(async () => {
129 root.render(null);
130 });
131 assertLog(['componentWillUnmount: text, default']);
132 });
133 });