Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 18 additions & 15 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -529,21 +529,24 @@ workflows:
# - "-r=www-modern --env=production --variant=true"

# TODO: Test more persistent configurations?
- download_base_build_for_sizebot:
filters:
branches:
ignore:
- main
requires:
- setup
- sizebot:
filters:
branches:
ignore:
- main
requires:
- download_base_build_for_sizebot
- yarn_build_combined

# Sizebot is disabled because the base revision of this 18.3 branch is
# too old
# - download_base_build_for_sizebot:
# filters:
# branches:
# ignore:
# - main
# requires:
# - setup
# - sizebot:
# filters:
# branches:
# ignore:
# - main
# requires:
# - download_base_build_for_sizebot
# - yarn_build_combined
- yarn_lint_build:
requires:
- yarn_build_combined
Expand Down
16 changes: 8 additions & 8 deletions ReactVersions.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,25 @@
//
// 0.0.0-experimental-241c4467e-20200129

const ReactVersion = '18.2.0';
const ReactVersion = '18.3.0';

// The label used by the @next channel. Represents the upcoming release's
// stability. Could be "alpha", "beta", "rc", etc.
const nextChannelLabel = 'next';

const stablePackages = {
'eslint-plugin-react-hooks': '4.6.0',
'jest-react': '0.14.0',
'eslint-plugin-react-hooks': '4.6.1',
'jest-react': '0.14.1',
react: ReactVersion,
'react-art': ReactVersion,
'react-dom': ReactVersion,
'react-is': ReactVersion,
'react-reconciler': '0.29.0',
'react-refresh': '0.14.0',
'react-reconciler': '0.29.1',
'react-refresh': '0.14.1',
'react-test-renderer': ReactVersion,
'use-subscription': '1.8.0',
'use-sync-external-store': '1.2.0',
scheduler: '0.23.0',
'use-subscription': '1.8.1',
'use-sync-external-store': '1.2.1',
scheduler: '0.23.1',
};

// These packages do not exist in the @next or @latest channel, only
Expand Down
4 changes: 2 additions & 2 deletions packages/jest-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
"homepage": "https://reactjs.org/",
"peerDependencies": {
"jest": "^23.0.1 || ^24.0.0 || ^25.1.0",
"react": "^18.1.0",
"react-test-renderer": "^18.1.0"
"react": "^18.3.0",
"react-test-renderer": "^18.3.0"
},
"files": [
"LICENSE",
Expand Down
4 changes: 2 additions & 2 deletions packages/react-art/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "react-art",
"description": "React ART is a JavaScript library for drawing vector graphics using React. It provides declarative and reactive bindings to the ART library. Using the same declarative API you can render the output to either Canvas, SVG or VML (IE8).",
"version": "18.1.0",
"version": "18.3.0",
"main": "index.js",
"repository": {
"type": "git",
Expand All @@ -28,7 +28,7 @@
"scheduler": "^0.22.0"
},
"peerDependencies": {
"react": "^18.1.0"
"react": "^18.3.0"
},
"files": [
"LICENSE",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,11 @@ describe('ReactHooksInspectionIntegration', () => {

await LazyFoo;

Scheduler.unstable_flushAll();
expect(() => {
Scheduler.unstable_flushAll();
}).toErrorDev([
'Foo: Support for defaultProps will be removed from function components in a future major release. Use JavaScript default parameters instead.',
]);

const childFiber = renderer.root._currentFiber();
const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
Expand Down
4 changes: 2 additions & 2 deletions packages/react-dom/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-dom",
"version": "18.1.0",
"version": "18.3.0",
"description": "React package for working with the DOM.",
"main": "index.js",
"repository": {
Expand All @@ -21,7 +21,7 @@
"scheduler": "^0.22.0"
},
"peerDependencies": {
"react": "^18.1.0"
"react": "^18.3.0"
},
"files": [
"LICENSE",
Expand Down
29 changes: 25 additions & 4 deletions packages/react-dom/src/__tests__/ReactComponent-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
let React;
let ReactDOM;
let ReactDOMServer;
let ReactFeatureFlags;
let ReactTestUtils;

describe('ReactComponent', () => {
Expand All @@ -21,6 +22,7 @@ describe('ReactComponent', () => {
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');
ReactFeatureFlags = require('shared/ReactFeatureFlags');
ReactTestUtils = require('react-dom/test-utils');
});

Expand All @@ -36,7 +38,7 @@ describe('ReactComponent', () => {
}).toThrowError(/Target container is not a DOM element./);
});

it('should throw when supplying a ref outside of render method', () => {
it('should throw when supplying a string ref outside of render method', () => {
let instance = <div ref="badDiv" />;
expect(function() {
instance = ReactTestUtils.renderIntoDocument(instance);
Expand Down Expand Up @@ -102,7 +104,7 @@ describe('ReactComponent', () => {
}
});

it('should support refs on owned components', () => {
it('should support string refs on owned components', () => {
const innerObj = {};
const outerObj = {};

Expand Down Expand Up @@ -133,10 +135,29 @@ describe('ReactComponent', () => {
}
}

ReactTestUtils.renderIntoDocument(<Component />);
expect(() => {
ReactTestUtils.renderIntoDocument(<Component />);
}).toErrorDev(
ReactFeatureFlags.warnAboutStringRefs
? [
'Warning: Component "div" contains the string ref "inner". ' +
'Support for string refs will be removed in a future major release. ' +
'We recommend using useRef() or createRef() instead. ' +
'Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref\n' +
' in div (at **)\n' +
' in Wrapper (at **)\n' +
' in Component (at **)',
'Warning: Component "Component" contains the string ref "outer". ' +
'Support for string refs will be removed in a future major release. ' +
'We recommend using useRef() or createRef() instead. ' +
'Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref\n' +
' in Component (at **)',
]
: [],
);
});

it('should not have refs on unmounted components', () => {
it('should not have string refs on unmounted components', () => {
class Parent extends React.Component {
render() {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ describe('ReactComponentLifeCycle', () => {
}
// you would *NEVER* do anything like this in real code!
this.state.hasRenderCompleted = true;
return <div ref="theDiv">I am the inner DIV</div>;
return <div ref={React.createRef()}>I am the inner DIV</div>;
}

componentWillUnmount() {
Expand Down Expand Up @@ -477,7 +477,9 @@ describe('ReactComponentLifeCycle', () => {
class Component extends React.Component {
render() {
return (
<Tooltip ref="tooltip" tooltip={<div>{this.props.tooltipText}</div>}>
<Tooltip
ref={React.createRef()}
tooltip={<div>{this.props.tooltipText}</div>}>
{this.props.text}
</Tooltip>
);
Expand Down
63 changes: 37 additions & 26 deletions packages/react-dom/src/__tests__/ReactCompositeComponent-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,18 @@ describe('ReactCompositeComponent', () => {
MorphingComponent = class extends React.Component {
state = {activated: false};

xRef = React.createRef();

_toggleActivatedState = () => {
this.setState({activated: !this.state.activated});
};

render() {
const toggleActivatedState = this._toggleActivatedState;
return !this.state.activated ? (
<a ref="x" onClick={toggleActivatedState} />
<a ref={this.xRef} onClick={toggleActivatedState} />
) : (
<b ref="x" onClick={toggleActivatedState} />
<b ref={this.xRef} onClick={toggleActivatedState} />
);
}
};
Expand All @@ -91,14 +93,16 @@ describe('ReactCompositeComponent', () => {
* reallocated again.
*/
ChildUpdates = class extends React.Component {
anchorRef = React.createRef();

getAnchor = () => {
return this.refs.anch;
return this.anchorRef.current;
};

render() {
const className = this.props.anchorClassOn ? 'anchorClass' : '';
return this.props.renderAnchor ? (
<a ref="anch" className={className} />
<a ref={this.anchorRef} className={className} />
) : (
<b />
);
Expand Down Expand Up @@ -186,11 +190,11 @@ describe('ReactCompositeComponent', () => {
it('should rewire refs when rendering to different child types', () => {
const instance = ReactTestUtils.renderIntoDocument(<MorphingComponent />);

expect(instance.refs.x.tagName).toBe('A');
expect(instance.xRef.current.tagName).toBe('A');
instance._toggleActivatedState();
expect(instance.refs.x.tagName).toBe('B');
expect(instance.xRef.current.tagName).toBe('B');
instance._toggleActivatedState();
expect(instance.refs.x.tagName).toBe('A');
expect(instance.xRef.current.tagName).toBe('A');
});

it('should not cache old DOM nodes when switching constructors', () => {
Expand Down Expand Up @@ -739,25 +743,28 @@ describe('ReactCompositeComponent', () => {
}

class Wrapper extends React.Component {
parentRef = React.createRef();
childRef = React.createRef();

render() {
return (
<Parent ref="parent">
<Child ref="child" />
<Parent ref={this.parentRef}>
<Child ref={this.childRef} />
</Parent>
);
}
}

const wrapper = ReactTestUtils.renderIntoDocument(<Wrapper />);

expect(wrapper.refs.parent.state.flag).toEqual(true);
expect(wrapper.refs.child.context).toEqual({flag: true});
expect(wrapper.parentRef.current.state.flag).toEqual(true);
expect(wrapper.childRef.current.context).toEqual({flag: true});

// We update <Parent /> while <Child /> is still a static prop relative to this update
wrapper.refs.parent.setState({flag: false});
wrapper.parentRef.current.setState({flag: false});

expect(wrapper.refs.parent.state.flag).toEqual(false);
expect(wrapper.refs.child.context).toEqual({flag: false});
expect(wrapper.parentRef.current.state.flag).toEqual(false);
expect(wrapper.childRef.current.context).toEqual({flag: false});
});

it('should pass context transitively', () => {
Expand Down Expand Up @@ -1142,25 +1149,28 @@ describe('ReactCompositeComponent', () => {
}

class Component extends React.Component {
static0Ref = React.createRef();
static1Ref = React.createRef();

render() {
if (this.props.flipped) {
return (
<div>
<Static ref="static0" key="B">
<Static ref={this.static0Ref} key="B">
B (ignored)
</Static>
<Static ref="static1" key="A">
<Static ref={this.static1Ref} key="A">
A (ignored)
</Static>
</div>
);
} else {
return (
<div>
<Static ref="static0" key="A">
<Static ref={this.static0Ref} key="A">
A
</Static>
<Static ref="static1" key="B">
<Static ref={this.static1Ref} key="B">
B
</Static>
</div>
Expand All @@ -1171,14 +1181,14 @@ describe('ReactCompositeComponent', () => {

const container = document.createElement('div');
const comp = ReactDOM.render(<Component flipped={false} />, container);
expect(ReactDOM.findDOMNode(comp.refs.static0).textContent).toBe('A');
expect(ReactDOM.findDOMNode(comp.refs.static1).textContent).toBe('B');
expect(ReactDOM.findDOMNode(comp.static0Ref.current).textContent).toBe('A');
expect(ReactDOM.findDOMNode(comp.static1Ref.current).textContent).toBe('B');

// When flipping the order, the refs should update even though the actual
// contents do not
ReactDOM.render(<Component flipped={true} />, container);
expect(ReactDOM.findDOMNode(comp.refs.static0).textContent).toBe('B');
expect(ReactDOM.findDOMNode(comp.refs.static1).textContent).toBe('A');
expect(ReactDOM.findDOMNode(comp.static0Ref.current).textContent).toBe('B');
expect(ReactDOM.findDOMNode(comp.static1Ref.current).textContent).toBe('A');
});

it('should allow access to findDOMNode in componentWillUnmount', () => {
Expand Down Expand Up @@ -1453,10 +1463,11 @@ describe('ReactCompositeComponent', () => {
this.state = {
color: 'green',
};
this.appleRef = React.createRef();
}

render() {
return <Apple color={this.state.color} ref="apple" />;
return <Apple color={this.state.color} ref={this.appleRef} />;
}
}

Expand Down Expand Up @@ -1502,15 +1513,15 @@ describe('ReactCompositeComponent', () => {
expect(renderCalls).toBe(2);

// Re-render base on state
instance.refs.apple.cut();
instance.appleRef.current.cut();
expect(renderCalls).toBe(3);

// No re-render based on state
instance.refs.apple.cut();
instance.appleRef.current.cut();
expect(renderCalls).toBe(3);

// Re-render based on state again
instance.refs.apple.eatSlice();
instance.appleRef.current.eatSlice();
expect(renderCalls).toBe(4);
});

Expand Down
Loading