Skip to content

Commit

Permalink
feat: use stable context API (#471)
Browse files Browse the repository at this point in the history
`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", 
```
  • Loading branch information
eps1lon authored and jquense committed Apr 15, 2019
1 parent 7eff7b2 commit aee4901
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 53 deletions.
8 changes: 4 additions & 4 deletions package.json
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
32 changes: 17 additions & 15 deletions src/Transition.js
Expand Up @@ -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'
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 }
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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 (
<TransitionGroupContext.Provider value={null}>
{children(status, childProps)}
</TransitionGroupContext.Provider>
)
}

const child = React.Children.only(children)
return React.cloneElement(child, childProps)
return (
// allows for nested Transitions
<TransitionGroupContext.Provider value={null}>
{React.cloneElement(child, childProps)}
</TransitionGroupContext.Provider>
)
}
}

Expand Down
29 changes: 16 additions & 13 deletions 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 {
Expand Down Expand Up @@ -31,31 +32,24 @@ const defaultProps = {
* items.
*/
class TransitionGroup extends React.Component {
static childContextTypes = {
transitionGroup: PropTypes.object.isRequired,
}

constructor(props, context) {
super(props, context)

const handleExited = this.handleExited.bind(this)

// 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() {
Expand Down Expand Up @@ -95,16 +89,25 @@ 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
delete props.enter
delete props.exit

if (Component === null) {
return children
return (
<TransitionGroupContext.Provider value={contextValue}>
{children}
</TransitionGroupContext.Provider>
)
}
return <Component {...props}>{children}</Component>
return (
<TransitionGroupContext.Provider value={contextValue}>
<Component {...props}>{children}</Component>
</TransitionGroupContext.Provider>
)
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/TransitionGroupContext.js
@@ -0,0 +1,3 @@
import React from 'react';

export default React.createContext(null);
46 changes: 25 additions & 21 deletions yarn.lock
Expand Up @@ -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"
Expand All @@ -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"
Expand Down Expand Up @@ -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"
Expand All @@ -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"
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit aee4901

Please sign in to comment.