This is a Livecoding Recap – an almost-weekly post about interesting things discovered while livecoding ?. Always under 500 words and with pictures. You can follow my channel, here. New content almost every Sunday at 2pm PDT. There’s live chat, come say hai ?
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 this jumping circle:
And ended with this transitioned circle:
It took me over an hour to realize that zooming-in would have made everyone’s lives easier, but here we are. Tiny little gifs for tiny little screens. Or big screens. The gifs are always tiny.
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 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 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}>
}
}
</circle>
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"></circle>
See, easy. :)
Join me next week when we clean this up to use dynamic getters, avoid importing the entire d3 library, and build some examples.
PS: the edited and improved versions of these videos are becoming a video course. Readers of the engineer package of React+d3js ES6 get the video course for free when it’s ready.
Continue reading about Livecoding #18: An abstract React transition component
Semantically similar articles hand-picked by GPT-4
- Livecoding #21: Use Babel for libraries, not Webpack
- Livecoding #19: It’s hard to package a library
- Livecoding #34: A Map of Global Migrations, Part 3
- Livecoding #13: rendering React components with canvas
- Livecoding #12: towards animating 10k+ elements with React
Learned something new?
Read more Software Engineering Lessons from Production
I write articles with real insight into the career and skills of a modern software engineer. "Raw and honest from the heart!" as one reader described them. Fueled by lessons learned over 20 years of building production code for side-projects, small businesses, and hyper growth startups. Both successful and not.
Subscribe below 👇
Software Engineering Lessons from Production
Join Swizec's Newsletter and get insightful emails 💌 on mindsets, tactics, and technical skills for your career. Real lessons from building production software. No bullshit.
"Man, love your simple writing! Yours is the only newsletter I open and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. 👌"
Have a burning question that you think I can answer? Hit me up on twitter and I'll do my best.
Who am I and who do I help? I'm Swizec Teller and I turn coders into engineers with "Raw and honest from the heart!" writing. No bullshit. Real insights into the career and skills of a modern software engineer.
Want to become a true senior engineer? Take ownership, have autonomy, and be a force multiplier on your team. The Senior Engineer Mindset ebook can help 👉 swizec.com/senior-mindset. These are the shifts in mindset that unlocked my career.
Curious about Serverless and the modern backend? Check out Serverless Handbook, for frontend engineers 👉 ServerlessHandbook.dev
Want to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz React components your whole team can understand with React for Data Visualization
Want to get my best emails on JavaScript, React, Serverless, Fullstack Web, or Indie Hacking? Check out swizec.com/collections
Did someone amazing share this letter with you? Wonderful! You can sign up for my weekly letters for software engineers on their path to greatness, here: swizec.com/blog
Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com
By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❤️