我有一个父组件index.js
render() {
const { firstName, token } = this.props.user;
if (token && firstName) {
return (
<View style={{ flex: 1 }}>
<HomeRoot />
</View>
);
}
console.log('=== ELSE');
return (
<View style={{ flex: 1 }}>
<SplashScreen />
</View>
);
}
}
&#13;
用户未登录时显示的SplashScreen:
// Methods imports.
import React from 'react';
import { View, Text, Image, TouchableOpacity, StyleSheet } from 'react-native';
import { connect } from 'react-redux';
import { Asset, AppLoading, Font, DangerZone } from 'expo';
import FadeInView from '../animations/FadeInView';
// Redux actions
import { signinUser } from '../../store/actions/actions';
const { Lottie } = DangerZone;
const styles = StyleSheet.create({
wrapper: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
// ...
});
function cacheImages(images) {
return images.map(image => {
if (typeof image === 'string') {
return Image.prefetch(image);
}
return Asset.fromModule(image).downloadAsync();
});
}
function cacheFonts(fonts) {
return fonts.map(font => Font.loadAsync(font));
}
class SplashScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
isReady: false
};
this.bgAnim = null;
}
setBgAnim(anim) {
// if (anim === null) {
// return;
// }
this.bgAnim = anim;
this.bgAnim.play();
}
async loadAssetsAsync() {
const imageAssets = cacheImages([
// ...
]);
const fontAssets = cacheFonts([{
'cabin-bold': CabinBold,
'league-spartan-bold': LeagueSpartanBold
}]);
await Promise.all([...imageAssets, ...fontAssets]);
}
render() {
if (!this.state.isReady) {
return (
<AppLoading
startAsync={this.loadAssetsAsync}
onFinish={() => this.setState({ isReady: true })}
/>
);
}
return (
<View style={styles.wrapper}>
<Lottie
ref={c => this.setBgAnim(c)}
resizeMode="cover"
style={{
position: 'absolute',
zIndex: 1,
left: 0,
top: 0,
width: '100%',
height: '100%',
}}
source={require('../../../assets/SPLASH_03.json')} // eslint-disable-line
/>
</View>
);t
}
}
export default connect(
null,
{ signinUser }
)(SplashScreen);
&#13;
signinUser
调用facebookAuth,然后将获取的用户个人资料和令牌存储在一个唯一的dispatch
中。
此时index.js
token && firstName
为真,SplashScreen
组件应该让他的位置HomeRoot
。
然而,它在SplashScreen
渲染方法崩溃:ref={c => this.setBgAnim(c)}
。如果我们删除此行,或者在c
为c
时检查放弃null
,一切都按预期工作。
为什么c
中的ref={c => this.setBgAnim(c)}
在此阶段为空?
如何以比检查null更好的方式处理此问题?
答案 0 :(得分:3)
当组件安装时,React将使用DOM元素调用ref回调,并在卸载时调用null。在componentDidMount或componentDidUpdate生命周期挂钩之前调用ref回调。
知道在某些点传递给回调的ref将为null,只需进行检查:
setBgAnim(anim) {
this.bgAnim = anim;
if(anim) {
this.bgAnim.play();
}
}
我不认为这种方法有问题。