Add unstable_deferredUpdates
This is needed to get the triangle demo working.
This commit is contained in:
parent
20f00045d3
commit
ead8ab7e2d
|
@ -1,5 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html style="width: 100%; height: 100%; overflow: hidden">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Fiber Example</title>
|
||||
|
@ -19,26 +19,156 @@
|
|||
</div>
|
||||
<script src="../../build/react.js"></script>
|
||||
<script src="../../build/react-dom-fiber.js"></script>
|
||||
<script>
|
||||
function ExampleApplication(props) {
|
||||
var elapsed = Math.round(props.elapsed / 100);
|
||||
var seconds = elapsed / 10 + (elapsed % 10 ? '' : '.0' );
|
||||
var message =
|
||||
'React has been successfully running for ' + seconds + ' seconds.';
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
|
||||
<script type="text/babel">
|
||||
var dotStyle = {
|
||||
position: 'absolute',
|
||||
background: '#61dafb',
|
||||
font: 'normal 15px sans-serif',
|
||||
textAlign: 'center',
|
||||
cursor: 'pointer',
|
||||
};
|
||||
|
||||
return React.DOM.p(null, message);
|
||||
var containerStyle = {
|
||||
position: 'absolute',
|
||||
transformOrigin: '0 0',
|
||||
left: '50%',
|
||||
top: '50%',
|
||||
width: '10px',
|
||||
height: '10px',
|
||||
background: '#eee',
|
||||
};
|
||||
|
||||
var targetSize = 25;
|
||||
|
||||
class Dot extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = { hover: false };
|
||||
}
|
||||
enter() {
|
||||
this.setState({
|
||||
hover: true
|
||||
});
|
||||
}
|
||||
leave() {
|
||||
this.setState({
|
||||
hover: false
|
||||
});
|
||||
}
|
||||
render() {
|
||||
var props = this.props;
|
||||
var s = props.size * 1.3;
|
||||
var style = {
|
||||
...dotStyle,
|
||||
width: s + 'px',
|
||||
height: s + 'px',
|
||||
left: (props.x) + 'px',
|
||||
top: (props.y) + 'px',
|
||||
borderRadius: (s / 2) + 'px',
|
||||
lineHeight: (s) + 'px',
|
||||
background: this.state.hover ? '#ff0' : dotStyle.background
|
||||
};
|
||||
return (
|
||||
<div style={style} onMouseEnter={() => this.enter()} onMouseLeave={() => this.leave()}>
|
||||
{this.state.hover ? '*' + props.text + '*' : props.text}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Call React.createFactory instead of directly call ExampleApplication({...}) in React.render
|
||||
var ExampleApplicationFactory = React.createFactory(ExampleApplication);
|
||||
function SierpinskiTriangle({ x, y, s, children }) {
|
||||
if (s <= targetSize) {
|
||||
return (
|
||||
<Dot
|
||||
x={x - (targetSize / 2)}
|
||||
y={y - (targetSize / 2)}
|
||||
size={targetSize}
|
||||
text={children}
|
||||
/>
|
||||
);
|
||||
return r;
|
||||
}
|
||||
var newSize = s / 2;
|
||||
var slowDown = false;
|
||||
if (slowDown) {
|
||||
var e = performance.now() + 0.8;
|
||||
while (performance.now() < e) {
|
||||
// Artificially long execution time.
|
||||
}
|
||||
}
|
||||
|
||||
s /= 2;
|
||||
|
||||
return [
|
||||
<SierpinskiTriangle x={x} y={y - (s / 2)} s={s}>
|
||||
{children}
|
||||
</SierpinskiTriangle>,
|
||||
<SierpinskiTriangle x={x - s} y={y + (s / 2)} s={s}>
|
||||
{children}
|
||||
</SierpinskiTriangle>,
|
||||
<SierpinskiTriangle x={x + s} y={y + (s / 2)} s={s}>
|
||||
{children}
|
||||
</SierpinskiTriangle>,
|
||||
];
|
||||
}
|
||||
SierpinskiTriangle.shouldComponentUpdate = function(oldProps, newProps) {
|
||||
var o = oldProps;
|
||||
var n = newProps;
|
||||
const res = !(
|
||||
o.x === n.x &&
|
||||
o.y === n.y &&
|
||||
o.s === n.s &&
|
||||
o.children === n.children
|
||||
);
|
||||
// console.log('shouldComponentUpdate', res);
|
||||
return res;
|
||||
};
|
||||
|
||||
class ExampleApplication extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = { seconds: 0 };
|
||||
this.tick = this.tick.bind(this);
|
||||
}
|
||||
componentDidMount() {
|
||||
this.invervalID = setInterval(this.tick, 1000);
|
||||
}
|
||||
tick() {
|
||||
ReactDOMFiber.unstable_deferredUpdates(() =>
|
||||
this.setState(state => ({ seconds: (state.seconds % 10) + 1 }))
|
||||
);
|
||||
}
|
||||
componentWillUnmount() {
|
||||
clearInterval(this.intervalID);
|
||||
}
|
||||
render() {
|
||||
const seconds = this.state.seconds;
|
||||
const elapsed = this.props.elapsed;
|
||||
const t = (elapsed / 1000) % 10;
|
||||
const scale = 1 + (t > 5 ? 10 - t : t) / 10;
|
||||
const transform = 'scaleX(' + (scale / 2.1) + ') scaleY(0.7) translateZ(0.1px)';
|
||||
return (
|
||||
<div style={{ ...containerStyle, transform }}>
|
||||
<div>
|
||||
<SierpinskiTriangle x={0} y={0} s={1000}>
|
||||
{this.state.seconds}
|
||||
</SierpinskiTriangle>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var start = new Date().getTime();
|
||||
setInterval(function() {
|
||||
function update() {
|
||||
ReactDOMFiber.render(
|
||||
ExampleApplicationFactory({elapsed: new Date().getTime() - start}),
|
||||
<ExampleApplication elapsed={new Date().getTime() - start} />,
|
||||
document.getElementById('container')
|
||||
);
|
||||
}, 50);
|
||||
requestAnimationFrame(update);
|
||||
}
|
||||
requestAnimationFrame(update);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -242,6 +242,8 @@ var ReactDOM = {
|
|||
|
||||
unstable_batchedUpdates: ReactGenericBatching.batchedUpdates,
|
||||
|
||||
unstable_deferredUpdates: DOMRenderer.deferredUpdates,
|
||||
|
||||
};
|
||||
|
||||
module.exports = ReactDOM;
|
||||
|
|
|
@ -79,6 +79,7 @@ export type Reconciler<C, I, TI> = {
|
|||
// FIXME: ESLint complains about type parameter
|
||||
batchedUpdates<A>(fn : () => A) : A,
|
||||
syncUpdates<A>(fn : () => A) : A,
|
||||
deferredUpdates<A>(fn : () => A) : A,
|
||||
/* eslint-enable no-undef */
|
||||
|
||||
// Used to extract the return value from the initial render. Legacy API.
|
||||
|
@ -103,6 +104,7 @@ module.exports = function<T, P, I, TI, C, CX>(config : HostConfig<T, P, I, TI, C
|
|||
performWithPriority,
|
||||
batchedUpdates,
|
||||
syncUpdates,
|
||||
deferredUpdates,
|
||||
} = ReactFiberScheduler(config);
|
||||
|
||||
return {
|
||||
|
@ -195,6 +197,8 @@ module.exports = function<T, P, I, TI, C, CX>(config : HostConfig<T, P, I, TI, C
|
|||
|
||||
syncUpdates,
|
||||
|
||||
deferredUpdates,
|
||||
|
||||
getPublicRootInstance(container : OpaqueNode) : (ReactComponent<any, any, any> | I | TI | null) {
|
||||
const root : FiberRoot = (container.stateNode : any);
|
||||
const containerFiber = root.current;
|
||||
|
|
|
@ -1076,11 +1076,22 @@ module.exports = function<T, P, I, TI, C, CX>(config : HostConfig<T, P, I, TI, C
|
|||
}
|
||||
}
|
||||
|
||||
function deferredUpdates<A>(fn : () => A) : A {
|
||||
const previousPriorityContext = priorityContext;
|
||||
priorityContext = LowPriority;
|
||||
try {
|
||||
return fn();
|
||||
} finally {
|
||||
priorityContext = previousPriorityContext;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
scheduleWork: scheduleWork,
|
||||
getPriorityContext: getPriorityContext,
|
||||
performWithPriority: performWithPriority,
|
||||
batchedUpdates: batchedUpdates,
|
||||
syncUpdates: syncUpdates,
|
||||
deferredUpdates: deferredUpdates,
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue