From 91f9b8616079621a261fd17c1ae5e2774af94eb9 Mon Sep 17 00:00:00 2001 From: Jimmy Jia Date: Fri, 14 Jul 2017 23:50:03 -0400 Subject: [PATCH] Clean up the README and migration guide a bit (#115) --- Migration.md | 257 ++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 30 +++--- migration.md | 271 --------------------------------------------------- 3 files changed, 273 insertions(+), 285 deletions(-) create mode 100644 Migration.md delete mode 100644 migration.md diff --git a/Migration.md b/Migration.md new file mode 100644 index 00000000..6ed3a2f8 --- /dev/null +++ b/Migration.md @@ -0,0 +1,257 @@ +# Migration Guide from v1 to v2 + +_A few notes to help with migrating from v1 to v2._ + +The `` component has been removed. A `` component has been added for use with the new `` component to accomplish the same tasks. + +### tl;dr: + +- `transitionName` -> `classNames` +- `transitionEnterTimeout` and `transitionLeaveTimeout` -> `timeout={{ exit, enter }}` +- `transitionAppear` -> `appear` +- `transitionEnter` -> `enter` +- `transitionLeave` -> `exit` + +## Walkthrough + +Let's take the [original docs example](https://github.com/reactjs/react-transition-group/tree/v1-stable/#high-level-api-csstransitiongroup) and migrate it. + +Starting with this CSS: + +```css +.example-enter { + opacity: 0.01; +} + +.example-enter.example-enter-active { + opacity: 1; + transition: opacity 500ms ease-in; +} + +.example-leave { + opacity: 1; +} + +.example-leave.example-leave-active { + opacity: 0.01; + transition: opacity 300ms ease-in; +} +``` + +And this component: + +```js +class TodoList extends React.Component { + constructor(props) { + super(props); + this.state = {items: ['hello', 'world', 'click', 'me']}; + this.handleAdd = this.handleAdd.bind(this); + } + + handleAdd() { + const newItems = this.state.items.concat([ + prompt('Enter some text') + ]); + this.setState({items: newItems}); + } + + handleRemove(i) { + let newItems = this.state.items.slice(); + newItems.splice(i, 1); + this.setState({items: newItems}); + } + + render() { + const items = this.state.items.map((item, i) => ( +
this.handleRemove(i)}> + {item} +
+ )); + + return ( +
+ + + {items} + +
+ ); + } +} +``` + +The most straightforward way to migrate is to use `` instead of ``: + +```diff + render() { + const items = this.state.items.map((item, i) => ( +
this.handleRemove(i)}> + {item} +
+ )); + + return ( +
+ +- ++ + {items} +- ++ +
+ ) + } +``` + +That doesn't get us much, since we haven't included anything to do the animation. For that, we'll need to wrap each item in a ``. First, though, let's adjust our CSS: + +```diff + .example-enter { + opacity: 0.01; + } + + .example-enter.example-enter-active { + opacity: 1; + transition: opacity 500ms ease-in; + } + +-.example-leave { ++.example-exit { + opacity: 1; + } + +-.example-leave.example-leave-active { ++.example-exit.example-exit-active { + opacity: 0.01; + transition: opacity 300ms ease-in; + } +``` + +All we did was replace `leave` with `exit`. v2 uses "exit" instead of "leave" to be more symmetric, avoiding awkwardness with English tenses (like with "entered" and "leaved"). + +Now we add the `` component: + +```diff + render() { + const items = this.state.items.map((item, i) => ( ++ +
this.handleRemove(i)}> + {item} +
++ + )); + + return ( +
+ + + {items} + +
+ ) + } +``` + +Note that we replaced `transitionName` with `classNames`. `` otherwise has essentially the same signature as ``. We also replaced `transitionEnterTimeout` and `transitionLeaveTimeout` with a single `timeout` prop with an object. + +> **Hint:** If your enter and exit timeouts are the same you can use the shorthand `timeout={500}`. + +If we want to make this a bit more encapsulated, we can wrap our `` into a separate component for reuse later: + +```js +const FadeTransition = (props) => ( + +); +``` + +We can then use it like: + +```diff + render() { + const items = this.state.items.map((item, i) => ( +- ++ +
this.handleRemove(i)}> + {item} +
+- ++
+ )); + + return ( +
+ + + {items} + +
+ ) + } +``` + +> **Hey!** You may not need `` at all! The lower level `` component is very flexible and may be easier to work with for simpler or more custom cases. Check out how we migrated [React-Bootstrap](https://react-bootstrap.github.io/)'s simple transitions to v2 for the [``](https://github.com/react-bootstrap/react-bootstrap/pull/2676/files#diff-4f938f648d04d4859be417d6590ca7c4) and [``](https://github.com/react-bootstrap/react-bootstrap/pull/2676/files#diff-8f766132cbd9f8de55ee05d63d75abd8) components. + + +## Wrapping `` Components + +The old `` component managed transitions through custom static lifecycle methods on its children. In v2 we removed that API in favor of requiring that `` be used with a `` component, and using traditional prop passing to communicate between the two. + +This means that ``s injects their children with ``-specific props that _must_ be passed through to the `` component for the transition to work. + +```js +const MyTransition = ({ children: child, ...props }) => ( + // NOTICE THE SPREAD! THIS IS REQUIRED! + + {transitionState => React.cloneElement(child, { + style: getStyleForTransitionState(transitionState) + })} + +); + +const MyList = () => ( + + {items.map(item => ( + {item} + )} + +); +``` + +Note how `` passes all props other than its own to ``. + + +## Lifecycle Callbacks + +As noted, child lifecycle methods have been removed. If you do need to do some work when the `` changes from one state to another, use the lifecycle callback props. + +```js + +``` + +Each callback is called with the DOM node of the transition component. Note also that there are now _three_ states per enter/exit transition instead of the original two. See the [full documentation](https://reactcommunity.org/react-transition-group/#Transition) for more details. diff --git a/README.md b/README.md index 84fdca3e..e1afbd8e 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,27 @@ -**ATTENTION!** To address many issues that have come up over the years, the API in v2.0.0 is different from the original React addon. +# react-transition-group [![npm][npm-badge]][npm] -**If you are migrating from `react-addons-transition-group` and `react-addons-css-transition-group`, [read the documentation for 1.x branch instead](https://github.com/reactjs/react-transition-group/tree/v1-stable) which is a drop-in replacement and is still actively maintained.** +> **ATTENTION!** To address many issues that have come up over the years, the API in v2 is different from that in the original React addon. +> +> **For a drop-in replacement for `react-addons-transition-group` and `react-addons-css-transition-group`, use the v1 release, which is still actively maintained. Documentation and code for that release are available on the [`v1-stable`](https://github.com/reactjs/react-transition-group/tree/v1-stable) branch.** +> +> You can send pull requests with v1 bugfixes against the `v1-stable` branch. -You can also send pull requests with 1.x bugfixes against the `v1-stable` branch. +A set of components for managing component states (including mounting and unmounting) over time, specifically designed with animation in mind. -# react-transition-group +## Documentation -A set of components for managing component states (including mounting) over time, -specifically designed with animation in mind. +- [**Main documentation**](https://reactcommunity.org/react-transition-group/) +- [Migration guide from v1](/Migration.md) -Check out the documentation at: [https://reactcommunity.org/react-transition-group/](https://reactcommunity.org/react-transition-group/) - -And the Migration details from v1: [https://github.com/reactjs/react-transition-group/blob/master/migration.md](https://github.com/reactjs/react-transition-group/blob/master/migration.md) - -### Examples +## Examples Clone the repo first: -```sh +``` git@github.com:reactjs/react-transition-group.git ``` -Then run `npm install` (or `yarn install`), and finally `npm run storybook` to -start a storybook instance you can navigate to in your browser and see some examples +Then run `npm install` (or `yarn`), and finally `npm run storybook` to start a storybook instance that you can navigate to in your browser to see the examples. + +[npm-badge]: https://img.shields.io/npm/v/react-transition-group.svg +[npm]: https://www.npmjs.org/package/react-transition-group diff --git a/migration.md b/migration.md deleted file mode 100644 index 998a5ad4..00000000 --- a/migration.md +++ /dev/null @@ -1,271 +0,0 @@ - -## Migrating from v1 to v2 - -A few notes to help with migrating from `v1` to `v2` - -### CSSTransitionGroup migration guide - -The `CSSTransitionGroup` has been removed, and a `CSSTransition` component has -been added and can be used with the new `TransitionGroup` component to accomplish the same tasks. - -**tl;dr;** - -- `transitionName` -> `classNames` -- `transitionEnterTimeout` and `transitionLeaveTimeout` -> `timeout={{ exit, enter }}` -- `transitionAppear` -> `appear` -- `transitionEnter` -> `enter` -- `transitionLeave` -> `exit` - -Lets take the original docs example and migrate it: - -```css -.example-enter { - opacity: 0.01; -} - -.example-enter.example-enter-active { - opacity: 1; - transition: opacity 500ms ease-in; -} - -.example-leave { - opacity: 1; -} - -.example-leave.example-leave-active { - opacity: 0.01; - transition: opacity 300ms ease-in; -} -``` - -And the component: - -```js -class TodoList extends React.Component { - constructor(props) { - super(props); - this.state = {items: ['hello', 'world', 'click', 'me']}; - this.handleAdd = this.handleAdd.bind(this); - } - - handleAdd() { - const newItems = this.state.items.concat([ - prompt('Enter some text') - ]); - this.setState({items: newItems}); - } - - handleRemove(i) { - let newItems = this.state.items.slice(); - newItems.splice(i, 1); - this.setState({items: newItems}); - } - - render() { - const items = this.state.items.map((item, i) => ( -
this.handleRemove(i)}> - {item} -
- )); - - return ( -
- - - {items} - -
- ); - } -} -``` - -The most straightforward way to migrate is to use `TransitionGroup` instead of -`CSSTransitionGroup` - -```diff -render() { - const items = this.state.items.map((item, i) => ( -
this.handleRemove(i)}> - {item} -
- )); - - return ( -
- -- -+ - {items} -- -+ -
- ) -} -``` - -That doesn't get us much, since we haven't included anything to do the animation. -For that we wrap each item in a `CSSTransition`, but first let's adjust our css. - -```diff -.example-enter { - opacity: 0.01; -} - -.example-enter.example-enter-active { - opacity: 1; - transition: opacity 500ms ease-in; -} - --.example-leave { -+.example-exit { - opacity: 1; -} - --.example-leave.example-leave-active { -+.example-exit.example-exit-active { - opacity: 0.01; - transition: opacity 300ms ease-in; -} -``` -All we did was replace the word `"leave"` with `"exit"`. Overall, `v2` uses -"exit" instead of "leave" to be more symmetrical, avoiding awkwardness -with english tenses (like "entered" and "leaved"). - -Now, at last we include the `CSSTransition` component. - -```diff -render() { - const items = this.state.items.map((item, i) => ( -+ -
this.handleRemove(i)}> - {item} -
-+ - )); - - return ( -
- - - {items} - -
- ) -} -``` - -Notice that we replaced `transitionName` with `classNames`, it has essentially the same signature. -We also replaced `transitionEnterTimeout` and `transitionLeaveTimeout` with a single -`timeout` prop that accepts an object. - -> Hint: If your enter and exit timeouts are the same you can use the shorthand: `timeout={500}` - -If we wanted to make this a bit more encapsulated we could wrap up our `CSSTransition` -into a separate component for reuse later! - -```js -const FadeTransition = (props) => ( - -) -``` - -And then use it like: - -```diff -render() { - const items = this.state.items.map((item, i) => ( -- -+ -
this.handleRemove(i)}> - {item} -
-- -+
- )); - - return ( -
- - - {items} - -
- ) -} -``` - -> HEY! You may not need CSSTransition at all! The lower level `Transition` component -is very flexible and may be easier to work with for simpler or custom cases. Check out how we migrated react-bootstrap's simple transitions to v2: [Collapse](https://github.com/react-bootstrap/react-bootstrap/pull/2676/files#diff-4f938f648d04d4859be417d6590ca7c4) and [Fade](https://github.com/react-bootstrap/react-bootstrap/pull/2676/files#diff-8f766132cbd9f8de55ee05d63d75abd8) components. - - -### TransitionGroup - -The old TransitionGroup managed transitions through custom static lifecycle methods -on its `children`. In `v2` we removed that API in favor of requiring that `TransitionGroup`s -be used with a `Transition` component, and traditional prop passing to communicate with the Group. - -Practically this means that `TransitionGroup` will inject it's `children` with `Transition` specific -props that **must** be passed through to the `Transition` component in order for the -transition to work. - -```js -const MyTransition = ({ children: child, ...props }) => ( - // NOTICE THE SPREAD! THIS IS REQUIRED! - - {(transitionState) => React.cloneElement(child, { - style: getStyleBasedOnTransitionState(transitionState) - })} - -) - -const MyList = () => ( - - {items.map((item) => ( - {item} - )} - -); -``` - -Notice how `MyTransition` passes all props it doesn't care about to `Transition`? - - -#### Callbacks - -As noted, child lifecycle methods have been removed. If you do need to do some work -when the Transition _changes_ from one state to another you can use the callback props. - -```js - -``` - -Each callback is called with the DOM `node` of the transition. Notice also that there -are now actually _3_ states per enter/exit transition vs the original 2. -See the documentation for more details.