* `react-addons-test-utils` -> `react-dom/test-utils`
Updating all references and docs on the `React.addons.TestUtils` and the
shallow renderer to refer to the correct targets.
Instead of:
```
const React = require('react');
// ...
React.addons.Testutils
// or
const ReactTestUtils = require('react-addons-test-utils');
```
we now show:
```
const ReactTestUtils = require('react-dom/test-utils');
```
And for shallow renderer, instead of:
```
const shallowRenderer = TestUtils.createRenderer();
```
we now show:
```
const shallowRenderer = require('react-test-renderer/shallow');
```
* Update the 'prev' and 'next' attributes of 'add-ons' docs
These flags are used to set arrow links to easily navigate through the
documents. They were wrong or missing in some of the 'add-ons' pages and
this bothered me when manually testing the updates from the previous
commit.
* Update syntax for instantiating shallow renderer
Missed this when updating the docs for the changes to shallow-renderer
in React 15.5.
* Fix pointers in addons docs
Thanks @bvaughn for catching this
* Make example of shallow renderer more consistent
We should show using the same variable names between code samples.
* Make names in example even more consistent
We should use the same variable name for the same thing across examples.
`renderer` -> `shallowRenderer`.
* Update docs to deprecate React<CSS>TransitionGroup
- removes link to the docs about `ReactCSSTransitionGroup` and
`ReactTransitionGroup` from the main navigation
- updates 'prev' and 'next' pointers to skip this page
- adds deprecation warning to the top of the page
- remove references to these modules from the packages README
- updates 'add-ons' main page to list this as a deprecated add-on
* Update `React.createClass` to `createReactClass` in the docs
The `React.createClass` method is being deprecated in favor of
`createReactClass`.
* Remove 'React.createClass' from top level API docs
It no longer makes sense to have a section for the 'createClass' method
in this page, since it won't be available as a top level method on
'React'.
I initially was going to pull the section about 'createClass' into a
separate page to add under 'addons' but it was short and duplicative of
the 'react-without-es6' docs. So I just linked to those.
* Remove *most* `React.PropTypes` from the docs
I am doing the docs for `context` in a separate commit because that case
was a bit less clear-cut.
We will no longer support `React.PropTypes` as a built-in feature of
React, and instead should direct folks to use the `PropTypes` project
that stands alone.
Rather than retaining the `React.PropTypes` examples and just revamping
them to show the use of the stand-alone `PropTypes` library with React,
it makes more sense to direct people to that project and reduce the
perceived API area and complexity of React core. The proper place to
document `PropTypes` is in the README or docs of that project, not in
React docs.
* Update `context` docs to not use `React.PropTypes`
We use `React.PropTypes` to define the `contextType` for the `context`
feature of React. It's unclear how this will work once `React.PropTypes`
is replaced by the external `PropTypes` library. Some options;
a) Deprecate `context`, either in v16 or shortly after. Seems reasonable
based on the intense warnings against using context that we have in the
docs -
https://facebook.github.io/react/docs/context.html#why-not-to-use-context
**Except** that probably some widely used libraries depend on it, like
`React-Router`.
b) Expect users will use external `PropTypes` library when defining
`contextTypes` and just don't do our `checkReactTypeSpec` against them
any more in v16.
c) Stop masking context and pass the whole context
unmasked everywhere. Worst option, do not recommend.
I went with `b` and assume that, for now, we will get users to use the
external `PropTypes` when defining context. I will update this PR if we
want a different approach.
* Remove 'addons' items from left nav, and deprecate 'addons' doc page
The plan:
[X] Remove links to 'addons' items from main navigation
[X] Add deprecation notices where appropriate, and update syntax to show
using the separate modules.
[ ] Update other references to 'React.addons' in docs. Coming in next
commit.
--- blocked but coming in future PRs
[ ] Link to a blog post describing the new locations of add-ons in the
deprecation notice on the '/docs/addons.html' page. Blocked until we
actually publish that blog post.
[ ] Move the docs for each add-on to the actual github repo where it now
lives.
[ ] Redirect the old add-ons doc permalinks to the docs in the separate
github repos for those modules.
[ ] Remove the old add-ons doc markdown files from React core docs.
* Remove references to `React.addons` from docs
Just misc. places where we referenced the 'addons' feature. All gone!
13 KiB
id, title, permalink, layout, category, redirect_from
| id | title | permalink | layout | category | redirect_from | |||
|---|---|---|---|---|---|---|---|---|
| animation | Animation Add-Ons | docs/animation.html | docs | Add-Ons |
|
Note:
ReactTransitionGroupandReactCSSTransitionGroupare both deprecated as of React v15.5.0. The recommendation is to useTransitionGroupandCSSTransitionGroupfrom 'react-transition-group' instead.
The ReactTransitionGroup add-on component is a low-level API for animation, and ReactCSSTransitionGroup is an add-on component for easily implementing basic CSS animations and transitions.
High-level API: ReactCSSTransitionGroup
ReactCSSTransitionGroup is a high-level API based on ReactTransitionGroup and is an easy way to perform CSS transitions and animations when a React component enters or leaves the DOM. It's inspired by the excellent ng-animate library.
Importing
import ReactCSSTransitionGroup from 'react-addons-css-transition-group'; // ES6
var ReactCSSTransitionGroup = require('react-addons-css-transition-group'); // ES5 with npm
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) => (
<div key={item} onClick={() => this.handleRemove(i)}>
{item}
</div>
));
return (
<div>
<button onClick={this.handleAdd}>Add Item</button>
<ReactCSSTransitionGroup
transitionName="example"
transitionEnterTimeout={500}
transitionLeaveTimeout={300}>
{items}
</ReactCSSTransitionGroup>
</div>
);
}
}
Note:
You must provide the
keyattribute for all children ofReactCSSTransitionGroup, even when only rendering a single item. This is how React will determine which children have entered, left, or stayed.
In this component, when a new item is added to ReactCSSTransitionGroup it will get the example-enter CSS class and the example-enter-active CSS class added in the next tick. This is a convention based on the transitionName prop.
You can use these classes to trigger a CSS animation or transition. For example, try adding this CSS and adding a new list item:
.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;
}
You'll notice that animation durations need to be specified in both the CSS and the render method; this tells React when to remove the animation classes from the element and -- if it's leaving -- when to remove the element from the DOM.
Animate Initial Mounting
ReactCSSTransitionGroup provides the optional prop transitionAppear, to add an extra transition phase at the initial mount of the component. There is generally no transition phase at the initial mount as the default value of transitionAppear is false. The following is an example which passes the prop transitionAppear with the value true.
render() {
return (
<ReactCSSTransitionGroup
transitionName="example"
transitionAppear={true}
transitionAppearTimeout={500}
transitionEnter={false}
transitionLeave={false}>
<h1>Fading at Initial Mount</h1>
</ReactCSSTransitionGroup>
);
}
During the initial mount ReactCSSTransitionGroup will get the example-appear CSS class and the example-appear-active CSS class added in the next tick.
.example-appear {
opacity: 0.01;
}
.example-appear.example-appear-active {
opacity: 1;
transition: opacity .5s ease-in;
}
At the initial mount, all children of the ReactCSSTransitionGroup will appear but not enter. However, all children later added to an existing ReactCSSTransitionGroup will enter but not appear.
Note:
The prop
transitionAppearwas added toReactCSSTransitionGroupin version0.13. To maintain backwards compatibility, the default value is set tofalse.However, the default values of
transitionEnterandtransitionLeavearetrueso you must specifytransitionEnterTimeoutandtransitionLeaveTimeoutby default. If you don't need either enter or leave animations, passtransitionEnter={false}ortransitionLeave={false}.
Custom Classes
It is also possible to use custom class names for each of the steps in your transitions. Instead of passing a string into transitionName you can pass an object containing either the enter and leave class names, or an object containing the enter, enter-active, leave-active, and leave class names. If only the enter and leave classes are provided, the enter-active and leave-active classes will be determined by appending '-active' to the end of the class name. Here are two examples using custom classes:
// ...
<ReactCSSTransitionGroup
transitionName={ {
enter: 'enter',
enterActive: 'enterActive',
leave: 'leave',
leaveActive: 'leaveActive',
appear: 'appear',
appearActive: 'appearActive'
} }>
{item}
</ReactCSSTransitionGroup>
<ReactCSSTransitionGroup
transitionName={ {
enter: 'enter',
leave: 'leave',
appear: 'appear'
} }>
{item2}
</ReactCSSTransitionGroup>
// ...
Animation Group Must Be Mounted To Work
In order for it to apply transitions to its children, the ReactCSSTransitionGroup must already be mounted in the DOM or the prop transitionAppear must be set to true.
The example below would not work, because the ReactCSSTransitionGroup is being mounted along with the new item, instead of the new item being mounted within it. Compare this to the Getting Started section above to see the difference.
render() {
const items = this.state.items.map((item, i) => (
<div key={item} onClick={() => this.handleRemove(i)}>
<ReactCSSTransitionGroup transitionName="example">
{item}
</ReactCSSTransitionGroup>
</div>
));
return (
<div>
<button onClick={this.handleAdd}>Add Item</button>
{items}
</div>
);
}
Animating One or Zero Items
In the example above, we rendered a list of items into ReactCSSTransitionGroup. However, the children of ReactCSSTransitionGroup can also be one or zero items. This makes it possible to animate a single element entering or leaving. Similarly, you can animate a new element replacing the current element. For example, we can implement a simple image carousel like this:
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
function ImageCarousel(props) {
return (
<div>
<ReactCSSTransitionGroup
transitionName="carousel"
transitionEnterTimeout={300}
transitionLeaveTimeout={300}>
<img src={props.imageSrc} key={props.imageSrc} />
</ReactCSSTransitionGroup>
</div>
);
}
Disabling Animations
You can disable animating enter or leave animations if you want. For example, sometimes you may want an enter animation and no leave animation, but ReactCSSTransitionGroup waits for an animation to complete before removing your DOM node. You can add transitionEnter={false} or transitionLeave={false} props to ReactCSSTransitionGroup to disable these animations.
Note:
When using
ReactCSSTransitionGroup, there's no way for your components to be notified when a transition has ended or to perform any more complex logic around animation. If you want more fine-grained control, you can use the lower-levelReactTransitionGroupAPI which provides the hooks you need to do custom transitions.
Low-level API: ReactTransitionGroup
Importing
import ReactTransitionGroup from 'react-addons-transition-group' // ES6
var ReactTransitionGroup = require('react-addons-transition-group') // ES5 with npm
ReactTransitionGroup is the basis for animations. When children are declaratively added or removed from it (as in the example above), special lifecycle hooks are called on them.
componentWillAppear()componentDidAppear()componentWillEnter()componentDidEnter()componentWillLeave()componentDidLeave()
Rendering a Different Component
ReactTransitionGroup renders as a span by default. You can change this behavior by providing a component prop. For example, here's how you would render a <ul>:
<ReactTransitionGroup component="ul">
{/* ... */}
</ReactTransitionGroup>
Any additional, user-defined, properties will become properties of the rendered component. For example, here's how you would render a <ul> with CSS class:
<ReactTransitionGroup component="ul" className="animated-list">
{/* ... */}
</ReactTransitionGroup>
Every DOM component that React can render is available for use. However, component does not need to be a DOM component. It can be any React component you want; even ones you've written yourself! Just write component={List} and your component will receive this.props.children.
Rendering a Single Child
People often use ReactTransitionGroup to animate mounting and unmounting of a single child such as a collapsible panel. Normally ReactTransitionGroup wraps all its children in a span (or a custom component as described above). This is because any React component has to return a single root element, and ReactTransitionGroup is no exception to this rule.
However if you only need to render a single child inside ReactTransitionGroup, you can completely avoid wrapping it in a <span> or any other DOM component. To do this, create a custom component that renders the first child passed to it directly:
function FirstChild(props) {
const childrenArray = React.Children.toArray(props.children);
return childrenArray[0] || null;
}
Now you can specify FirstChild as the component prop in <ReactTransitionGroup> props and avoid any wrappers in the result DOM:
<ReactTransitionGroup component={FirstChild}>
{someCondition ? <MyComponent /> : null}
</ReactTransitionGroup>
This only works when you are animating a single child in and out, such as a collapsible panel. This approach wouldn't work when animating multiple children or replacing the single child with another child, such as an image carousel. For an image carousel, while the current image is animating out, another image will animate in, so <ReactTransitionGroup> needs to give them a common DOM parent. You can't avoid the wrapper for multiple children, but you can customize the wrapper with the component prop as described above.
Reference
componentWillAppear()
componentWillAppear(callback)
This is called at the same time as componentDidMount() for components that are initially mounted in a TransitionGroup. It will block other animations from occurring until callback is called. It is only called on the initial render of a TransitionGroup.
componentDidAppear()
componentDidAppear()
This is called after the callback function that was passed to componentWillAppear is called.
componentWillEnter()
componentWillEnter(callback)
This is called at the same time as componentDidMount() for components added to an existing TransitionGroup. It will block other animations from occurring until callback is called. It will not be called on the initial render of a TransitionGroup.
componentDidEnter()
componentDidEnter()
This is called after the callback function that was passed to componentWillEnter() is called.
componentWillLeave()
componentWillLeave(callback)
This is called when the child has been removed from the ReactTransitionGroup. Though the child has been removed, ReactTransitionGroup will keep it in the DOM until callback is called.
componentDidLeave()
componentDidLeave()
This is called when the willLeave callback is called (at the same time as componentWillUnmount()).