chenglou / chenglou/react-motion

A fix(?) addressing staleness in TransitionMotion:clearUnreadPropStyles

Open
#521 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
21.9k
Forks
1.1k
PR merge metrics
No merged PRs in 30d

Description

In TransitionMotion:clearUnreadPropStyles, we acknowledge that, because style objects can carry data, we can't directly compare them to check for staleness.

```
// unlike the other 2 components, we can't detect staleness and optionally
// opt out of setState here. each style object's data might contain new
// stuff we're not/cannot compare
this.setState({
currentStyles,
currentVelocities,
mergedPropsStyles,
lastIdealStyles,
lastIdealVelocities,
});
```

Leaving staleness unchecked in this case leads to issues when a rerender is triggered very quickly, because the styles have not been interpolated even once . This can lead to mounting or unmounting transitions that 'jitter', that is, they restart again and again. I can post an example video to show what I mean.

When I insert the following (basic) check for staleness, these bugs (for me) disappear.
```
// A simple check for staleness
let stale = false;
let oldStyle, newStyle, curVelocity;

// In rare cases, the lengths of currentStyles, this.state.currentStyles,
// and currentVelocities can differ. This check makes sure we only
// check for staleness on styles that are represented in all
// 3 arrays
let shortestArray = [currentStyles,
this.state.currentStyles,
currentVelocities].reduce((short, current) => {
return (short.length < current.length? short: current)
}, currentStyles);

// For every well-represented style...
for(let i in shortestArray) {
// Check every key (except for data)
for(let key in this.state.currentStyles[i]) {
if(key != 'data'){
oldStyle = this.state.currentStyles[i][key];
newStyle = currentStyles[i][key];
curVelocity = currentVelocities[i][key];
// IF VELOCITY IS 0 BUT OLDSTYLE DIFFERS FROM NEWSTYLE
// THE STYLES ARE PROBABLY STALE
if((oldStyle != newStyle) && (curVelocity == 0)) {
stale = true;
break;
}
// IF NEWSTYLE 'POINTS' IN A DIFFERENT DIRECTION THAN
// CURVELOCITY, IT IS PROBABLY STALE
if(((oldStyle - newStyle)*curVelocity) < 0) {
stale = true;
break;
}
}
}
}

// If currentStyles passed our check for staleness,
// then update!
if(!stale)
_this.setState({
currentStyles: currentStyles,
currentVelocities: currentVelocities,
mergedPropsStyles: mergedPropsStyles,
lastIdealStyles: lastIdealStyles,
lastIdealVelocities: lastIdealVelocities
});
```
Is there something wrong with this check for staleness?

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.