[Fresh] Transfer refs when remounting (#16241)
* Add a failing test for refs and remounting * Transfer ref when remounting
Dan Abramov committed
Jul 29, 2019 at 17:19 UTC
9914a19190296ca7e0fd65f7c4f6fe5cc42e29a4
2 files changed
+75
packages/react-reconciler/src/ReactFiberBeginWork.js
+1
@@ -2586,6 +2586,7 @@ function remountFiber(
2586
newWorkInProgress.index = oldWorkInProgress.index;
2587
newWorkInProgress.sibling = oldWorkInProgress.sibling;
2588
newWorkInProgress.return = oldWorkInProgress.return;
2589
+ newWorkInProgress.ref = oldWorkInProgress.ref;
2590
2591
// Replace the child/sibling pointers above it.
2592
if (oldWorkInProgress === returnFiber.child) {
packages/react-refresh/src/__tests__/ReactFresh-test.js
+74
@@ -2943,6 +2943,80 @@ describe('ReactFresh', () => {
2943
}
2944
});
2945
2946
+ it('updates refs when remounting', () => {
2947
+ if (__DEV__) {
2948
+ const testRef = React.createRef();
2949
+ render(
2950
+ () => {
2951
+ class Hello extends React.Component {
2952
+ getColor() {
2953
+ return 'green';
2954
+ }
2955
+ render() {
2956
+ return <p />;
2957
+ }
2958
+ }
2959
+ $RefreshReg$(Hello, 'Hello');
2960
+ return Hello;
2961
+ },
2962
+ {ref: testRef},
2963
+ );
2964
+ expect(testRef.current.getColor()).toBe('green');
2965
+
2966
+ patch(() => {
2967
+ class Hello extends React.Component {
2968
+ getColor() {
2969
+ return 'orange';
2970
+ }
2971
+ render() {
2972
+ return <p />;
2973
+ }
2974
+ }
2975
+ $RefreshReg$(Hello, 'Hello');
2976
+ });
2977
+ expect(testRef.current.getColor()).toBe('orange');
2978
+
2979
+ patch(() => {
2980
+ const Hello = React.forwardRef((props, ref) => {
2981
+ React.useImperativeHandle(ref, () => ({
2982
+ getColor() {
2983
+ return 'pink';
2984
+ },
2985
+ }));
2986
+ return <p />;
2987
+ });
2988
+ $RefreshReg$(Hello, 'Hello');
2989
+ });
2990
+ expect(testRef.current.getColor()).toBe('pink');
2991
+
2992
+ patch(() => {
2993
+ const Hello = React.forwardRef((props, ref) => {
2994
+ React.useImperativeHandle(ref, () => ({
2995
+ getColor() {
2996
+ return 'yellow';
2997
+ },
2998
+ }));
2999
+ return <p />;
3000
+ });
3001
+ $RefreshReg$(Hello, 'Hello');
3002
+ });
3003
+ expect(testRef.current.getColor()).toBe('yellow');
3004
+
3005
+ patch(() => {
3006
+ const Hello = React.forwardRef((props, ref) => {
3007
+ React.useImperativeHandle(ref, () => ({
3008
+ getColor() {
3009
+ return 'yellow';
3010
+ },
3011
+ }));
3012
+ return <p />;
3013
+ });
3014
+ $RefreshReg$(Hello, 'Hello');
3015
+ });
3016
+ expect(testRef.current.getColor()).toBe('yellow');
3017
+ }
3018
+ });
3019
+
3020
it('remounts on conversion from class to function and back', () => {
3021
if (__DEV__) {
3022
let HelloV1 = render(() => {