Files
react-navigation/src/screens.web.js
Lorenzo Sciandra c590283359 Enhancement: change to useScreens to enableScreens (#99)
This wants to be a small PR to improve the usability of the library, based on this conversation: https://twitter.com/grifotv/status/1127847192067215360.

Since the release of RNS there has been a new major player in the React game: hooks. And sadly `useScreens` recalls too closely Hooks, and this can lead to misunderstanding.

Changing it to `enableScreens` will make the difference clear, but at the same time it will be a BREAKING CHANGE for everyone using the lib.

So if we prefer to keep it around as useScreens I'm ok with it too, and we can close this.

Also, I did some tweaks to the README + fix some typos.
2019-10-11 21:57:48 +02:00

114 lines
2.5 KiB
JavaScript

import debounce from 'debounce';
import React from 'react';
import { Animated, View } from 'react-native';
let _shouldEnableScreens = true;
export function enableScreens(shouldEnableScreens = true) {
if (shouldEnableScreens) {
console.warn(
'react-native-screens is not fully supported on this platform yet.'
);
}
_shouldEnableScreens = shouldEnableScreens;
}
export function screensEnabled() {
return _shouldEnableScreens;
}
function isAnimatedValue(value) {
return value && value.__getValue && value.addListener;
}
function isPropTruthy(prop) {
let activeValue = prop;
if (isAnimatedValue(prop)) {
activeValue = prop.__getValue();
}
return !!activeValue;
}
export class Screen extends React.Component {
static defaultProps = {
active: true,
};
listenerId = null;
constructor(props) {
super(props);
this._onAnimatedValueUpdated = debounce(this._onAnimatedValueUpdated, 10);
this._addListener(props.active);
}
componentWillUnmount() {
this._removeListener(this.props.active);
}
_addListener = possibleListener => {
if (this.listenerId)
throw new Error(
'Screen: Attempting to observe an animated value while another value is already observed.'
);
if (isAnimatedValue(possibleListener)) {
this.listenerId = possibleListener.addListener(
this._onAnimatedValueUpdated
);
}
};
_removeListener = possibleListener => {
if (isAnimatedValue(possibleListener)) {
possibleListener.removeListener(this.listenerId);
this.listenerId = null;
}
};
shouldComponentUpdate({ active: nextActive }) {
const { active } = this.props;
if (nextActive !== active) {
this._removeListener(active);
this._addListener(nextActive);
this._updateDisplay(isPropTruthy(nextActive));
return false;
}
return true;
}
_onAnimatedValueUpdated = ({ value }) => {
this._updateDisplay(!!value);
};
_updateDisplay = isActive => {
if (isActive === undefined) {
isActive = isPropTruthy(this.props.active);
}
const display = isActive ? 'flex' : 'none';
this.setNativeProps({ style: { display } });
};
setNativeProps = nativeProps => {
if (this._view) {
this._view.setNativeProps(nativeProps);
}
};
_setRef = view => {
this._view = view;
this._updateDisplay();
};
render() {
return <Animated.View {...this.props} ref={this._setRef} />;
}
}
export const ScreenContainer = View;
export const NativeScreen = View;
export const NativeScreenContainer = View;