From aee49011ef0f9286f26150f1f47a3953fbe984a9 Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Mon, 15 Apr 2019 15:50:22 +0200 Subject: [PATCH] feat: use stable context API (#471) `React@16.6.0` allows usage of static `contextType`. With `16.0.0` we would need a higher-order component that puts the context value into props since `Transition` needs to have access to the context in its constructor. Partial fix for #429 BREAKING CHANGE: use new style react context ```diff // package.json -"react": "^15.0.0", +"react": "^16.6.0", -"react-dom": "^15.0.0", +"react-dom": "^16.6.0", ``` --- package.json | 8 +++--- src/Transition.js | 32 ++++++++++++------------ src/TransitionGroup.js | 29 ++++++++++++---------- src/TransitionGroupContext.js | 3 +++ yarn.lock | 46 +++++++++++++++++++---------------- 5 files changed, 65 insertions(+), 53 deletions(-) create mode 100644 src/TransitionGroupContext.js diff --git a/package.json b/package.json index aae0d578..12e6bb91 100644 --- a/package.json +++ b/package.json @@ -50,8 +50,8 @@ ] }, "peerDependencies": { - "react": ">=15.0.0", - "react-dom": ">=15.0.0" + "react": ">=16.6.0", + "react-dom": ">=16.6.0" }, "dependencies": { "dom-helpers": "^3.4.0", @@ -86,8 +86,8 @@ "husky": "^1.3.1", "jest": "^24.7.1", "prettier": "^1.16.4", - "react": "^16.5.2", - "react-dom": "^16.5.2", + "react": "~16.6.3", + "react-dom": "~16.6.3", "release-script": "^1.0.2", "rimraf": "^2.6.3", "rollup": "^1.9.0", diff --git a/src/Transition.js b/src/Transition.js index cf7dbea1..a6a8e2a8 100644 --- a/src/Transition.js +++ b/src/Transition.js @@ -4,6 +4,7 @@ import ReactDOM from 'react-dom' import { polyfill } from 'react-lifecycles-compat' import { timeoutsShape } from './utils/PropTypes' +import TransitionGroupContext from './TransitionGroupContext' export const UNMOUNTED = 'unmounted' export const EXITED = 'exited' @@ -103,17 +104,12 @@ export const EXITING = 'exiting' * `'exiting'` to `'exited'`. */ class Transition extends React.Component { - static contextTypes = { - transitionGroup: PropTypes.object, - } - static childContextTypes = { - transitionGroup: () => {}, - } + static contextType = TransitionGroupContext constructor(props, context) { super(props, context) - let parentGroup = context.transitionGroup + let parentGroup = context // In the context of a TransitionGroup all enters are really appears let appear = parentGroup && !parentGroup.isMounting ? props.enter : props.appear @@ -142,10 +138,6 @@ class Transition extends React.Component { this.nextCallback = null } - getChildContext() { - return { transitionGroup: null } // allows for nested Transitions - } - static getDerivedStateFromProps({ in: nextIn }, prevState) { if (nextIn && prevState.status === UNMOUNTED) { return { status: EXITED } @@ -232,8 +224,8 @@ class Transition extends React.Component { performEnter(node, mounting) { const { enter } = this.props - const appearing = this.context.transitionGroup - ? this.context.transitionGroup.isMounting + const appearing = this.context + ? this.context.isMounting : mounting const timeouts = this.getTimeouts() @@ -360,11 +352,21 @@ class Transition extends React.Component { delete childProps.onExited if (typeof children === 'function') { - return children(status, childProps) + // allows for nested Transitions + return ( + + {children(status, childProps)} + + ) } const child = React.Children.only(children) - return React.cloneElement(child, childProps) + return ( + // allows for nested Transitions + + {React.cloneElement(child, childProps)} + + ) } } diff --git a/src/TransitionGroup.js b/src/TransitionGroup.js index d098a3b5..9f6e2c72 100644 --- a/src/TransitionGroup.js +++ b/src/TransitionGroup.js @@ -1,6 +1,7 @@ import PropTypes from 'prop-types' import React from 'react' import { polyfill } from 'react-lifecycles-compat' +import TransitionGroupContext from './TransitionGroupContext' import { @@ -31,10 +32,6 @@ const defaultProps = { * items. */ class TransitionGroup extends React.Component { - static childContextTypes = { - transitionGroup: PropTypes.object.isRequired, - } - constructor(props, context) { super(props, context) @@ -42,20 +39,17 @@ class TransitionGroup extends React.Component { // Initial children should all be entering, dependent on appear this.state = { + contextValue: { isMounting: true }, handleExited, firstRender: true, } } - getChildContext() { - return { - transitionGroup: { isMounting: !this.appeared }, - } - } - componentDidMount() { - this.appeared = true this.mounted = true + this.setState({ + contextValue: { isMounting: false }, + }) } componentWillUnmount() { @@ -95,6 +89,7 @@ class TransitionGroup extends React.Component { render() { const { component: Component, childFactory, ...props } = this.props + const { contextValue } = this.state const children = values(this.state.children).map(childFactory) delete props.appear @@ -102,9 +97,17 @@ class TransitionGroup extends React.Component { delete props.exit if (Component === null) { - return children + return ( + + {children} + + ) } - return {children} + return ( + + {children} + + ) } } diff --git a/src/TransitionGroupContext.js b/src/TransitionGroupContext.js new file mode 100644 index 00000000..51b82c7d --- /dev/null +++ b/src/TransitionGroupContext.js @@ -0,0 +1,3 @@ +import React from 'react'; + +export default React.createContext(null); diff --git a/yarn.lock b/yarn.lock index f0f57642..ac4aa63c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9926,15 +9926,6 @@ react-docgen@^3.0.0-rc.1: node-dir "^0.1.10" recast "^0.16.0" -react-dom@^16.5.2: - version "16.5.2" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.5.2.tgz#b69ee47aa20bab5327b2b9d7c1fe2a30f2cfa9d7" - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.2" - schedule "^0.5.0" - react-dom@^16.6.3: version "16.7.0" resolved "http://storage.mds.yandex.net/get-npm/38095/react-dom-16.7.0.tgz#a17b2a7ca89ee7390bc1ed5eb81783c7461748b8" @@ -9945,6 +9936,16 @@ react-dom@^16.6.3: prop-types "^15.6.2" scheduler "^0.12.0" +react-dom@~16.6.3: + version "16.6.3" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.6.3.tgz#8fa7ba6883c85211b8da2d0efeffc9d3825cccc0" + integrity sha512-8ugJWRCWLGXy+7PmNh8WJz3g1TaTUt1XyoIcFN+x0Zbkoz+KKdUyx1AQLYJdbFXjuF41Nmjn5+j//rxvhFjgSQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.11.2" + react-error-overlay@^5.1.0: version "5.1.1" resolved "http://storage.mds.yandex.net/get-npm/69187/react-error-overlay-5.1.1.tgz#56f0439f001ff3588da0f479a86482ccb1e708cb" @@ -10046,15 +10047,6 @@ react-treebeard@^3.1.0: shallowequal "^1.1.0" velocity-react "^1.4.1" -react@^16.5.2: - version "16.5.2" - resolved "https://registry.yarnpkg.com/react/-/react-16.5.2.tgz#19f6b444ed139baa45609eee6dc3d318b3895d42" - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.2" - schedule "^0.5.0" - react@^16.6.3: version "16.7.0" resolved "http://storage.mds.yandex.net/get-npm/45674/react-16.7.0.tgz#b674ec396b0a5715873b350446f7ea0802ab6381" @@ -10065,6 +10057,16 @@ react@^16.6.3: prop-types "^15.6.2" scheduler "^0.12.0" +react@~16.6.3: + version "16.6.3" + resolved "https://registry.yarnpkg.com/react/-/react-16.6.3.tgz#25d77c91911d6bbdd23db41e70fb094cc1e0871c" + integrity sha512-zCvmH2vbEolgKxtqXL2wmGCUxUyNheYn/C+PD1YAjfxHC54+MhdruyhO7QieQrYsYeTxrn93PM2y0jRH1zEExw== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.11.2" + read-cmd-shim@^1.0.1, read-cmd-shim@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz#2d5d157786a37c055d22077c32c53f8329e91c7b" @@ -10772,10 +10774,12 @@ sax@^1.2.4, sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" -schedule@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/schedule/-/schedule-0.5.0.tgz#c128fffa0b402488b08b55ae74bb9df55cc29cc8" +scheduler@^0.11.2: + version "0.11.3" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.11.3.tgz#b5769b90cf8b1464f3f3cfcafe8e3cd7555a2d6b" + integrity sha512-i9X9VRRVZDd3xZw10NY5Z2cVMbdYg6gqFecfj79USv1CFN+YrJ3gIPRKf1qlY+Sxly4djoKdfx1T+m9dnRB8kQ== dependencies: + loose-envify "^1.1.0" object-assign "^4.1.1" scheduler@^0.12.0: