DZone
Web Dev Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Web Dev Zone > Livecoding: An Abstract React Transition Component

Livecoding: An Abstract React Transition Component

Follow along as a ReactJS thought leader shows off his first open-source contribution to the React ecosystem, and show how to us it to create smooth transitions.

Swizec Teller user avatar by
Swizec Teller
·
May. 22, 17 · Web Dev Zone · Tutorial
Like (1)
Save
Tweet
6.13K Views

Join the DZone community and get the full member experience.

Join For Free

This week we made a circle bounce back and forth.

Trivial, right? Yes, as trivial as it gets. The bouncing circle wasn’t the point, the point was how it’s made. This: react-transitionable-component. My first not-just-a-cool-experiment open-source contribution to the React ecosystem.

It’s an abstract component that makes building transitions easy.

Over the past few weeks, I’ve noticed that making a transition always follows the same pattern: move props to state, render from state instead of props, use d3.transition to transition prop values on every componentWillReceiveProps. What if we can abstract all that work away? 

We started with a jerky, jumping circle.

And ended with a smoothly transitioning circle.

Making a circle that transitions like that isn’t hard. It takes about twenty minutes to show and explain to a novice in both React and D3. At least that’s how much it takes when I do workshops.

So who cares about making an abstraction, right? I care. Doing it from scratch every time gets old, fast. I wanted a way to say, “make this component use transitions for everything,” without worrying about implementation every time.

As you can expect from a project that took less than two hours from start to finish, there’s little code to show. 40 lines that look like this:

class TransitionableComponent extends Component {
    constructor(props) {
        // copy all props to state
        // call _defineEasing and _defineDuration
    }

    _defineEasing(easing) {
        // if this.easing undefined, get easing function from d3
    }

    _defineDuration(duration) {
        // if this.duration undefined, set it
    }

    componentWillReceiveProps(newProps) {
        this._defineEasing(newProps.easing);
        this._defineDuration(newProps.duration);

        const node = d3.select(this.refs.node);

        let transition = node.transition()
                             .ease(this.easing);

        if (this.duration !== undefined) {
            transition.duration(this.duration);
        }

        Object.keys(newProps)
              .forEach((k) => {
                  transition.attr(k, newProps[k]);
              });

        transition.on('end', () => this.setState(newProps));
    }
}

I cut out the boring bits. You can see them on GitHub, here.

The fun bit is in componentWillReceiveProps. We update our easing function and our duration, which should’ve been dynamic getters instead. Then we get the node and start a transition()with an easing function, and a duration, if it’s there. After that, we walk through every prop and add it to the pile of transitioning attributes with .attr. When the transition is over, we use the 'end' callback to update the component state and ensure React understands what’s going on.

You’ll notice TransitionableComponent doesn’t have a render()function. It’s an abstract component meant to be extended by a real component. Something like this:

class Circle extends TransitionableComponent {
    render() {
        return <circle cx={this.state.cx}
                       cy={this.state.cy}
                       r={this.state.r} />
    }
}

That’s a transitionable circle now. Any props passed into it are transitioned. You have to be careful to use this.state instead of this.props when using them though.

Using the Circle component looks like this:

    <Circle cx="100" cy="100" r="5" easing="cubicInOut" duration="1500" />

See, easy.

Join me next time when we clean this up to use dynamic getters, avoid importing the entire d3 library and build some examples.

React (JavaScript library)

Published at DZone with permission of Swizec Teller, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • How To Check for JSON Insecure Deserialization (JID) Attacks With Java
  • Top 7 Features in Jakarta EE 10 Release
  • Component Testing of Frontends: Karate Netty Project
  • What Developers Need to Know About Table Partition Pruning

Comments

Web Dev Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo