我注意到我的测试应用中存在一些奇怪的行为。具有“componentWillReceiveProps”功能的组件是双重调用。按钮点击后应该只调用一次,但它的次数是奇怪的。 我有3个组件: 测试 - 启动组件 SetMessage - 从Test接收道具并传递给Animation组件 动画 - 从SetMessage和显示中接收道具
所以单击按钮后,组件和功能应该像这样调用:
Test-> SetMessage(函数:reciveProps - > setMsg)然后 动画(功能:reciveProps-> showMsg)。
但在我的情况下是:
测试 - > SetMessage(函数:reciveProps)然后动画(函数:reciveProps-> showMsg)然后 SetMessage(函数:changeMsg)然后 动画(功能:reciveProps-> showMsg)。
我想知道,如果这是正常和罚款?如果没有,为什么会发生以及如何解决?
Bellow所有代码和日志屏幕。
Index.android.js:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
Navigator,
View
} from 'react-native';
import Test from './app/components/Test/Test';
export default class testApp extends Component {
render(){
return(
<View style={{flex:1}}>
<Test/>
</View>
)
}
}
AppRegistry.registerComponent('testApp', () => testApp);
Test.js:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
Button,
View,
Animated,
Easing,
Switch,
} from 'react-native';
import SetMessage from '../SetMessage/SetMessage';
export default class Test extends Component{
constructor(){
super();
this.state = {
sendMsg:'plus'
}
}
change(){
if(this.state.sendMsg==='plus'){
this.setState({sendMsg:'minus'});
}else{
this.setState({
sendMsg:'minus'
});
}
console.log('Test com ')
}
render(){
return (
<View>
<Button
onPress={this.change.bind(this)}
title={'Start'}
/>
<SetMessage msg={this.state.sendMsg}/>
</View>
)
}
}
AppRegistry.registerComponent('Test', () => Test);
SetMessage.js:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
Button,
View,
Animated,
Easing,
Switch,
} from 'react-native';
import Animation from '../Animation/Animation';
export default class SetMessage extends Component{
constructor(){
super();
this.state = {
test:'',
sendMsg:''
}
}
componentWillReceiveProps(nextProps){
this.setState({
test:nextProps.msg
},()=>this.setMsg());
console.log('SetMessage F - ReciveProp'+this.state.sendMsg)
}
setMsg(){
console.log('SetMessage F - Change Msg '+this.state.sendMsg);
this.setState({
sendMsg:this.state.test
})
}
render(){
return (
<View>
<Animation msg={this.state.sendMsg}/>
</View>
)
}
}
AppRegistry.registerComponent('SetMessage', () => SetMessage);
Animation.js
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Animated,
Easing,
Switch,
} from 'react-native';
export default class Animation extends Component{
constructor(){
super();
this.state = {
msg:'',
bottom: new Animated.Value(-50)
}
}
componentWillReceiveProps(nextProp){
console.log('Animation F - reciveProp'+this.state.msg);
this.setState({
msg:nextProp.msg
},()=>this.showMsg());
}
showMsg(){
console.log('Animation F - showMsg '+this.state.msg);
if(this.state.msg!='') {
Animated.sequence([
Animated.timing( // Animate over time
this.state.bottom, // The animated value to drive
{
toValue: 0,
duration: 500 // Animate to opacity: 1, or fully opaque
}),
Animated.delay(1000),
Animated.timing(this.state.bottom, // The animated value to drive
{
toValue: -50,
duration: 500 // Animate to opacity: 1, or fully opaque
}),
]).start();
}
}
render(){
return (
<View style={styles.mainCont}>
<Animated.View style={{
height:50,
width:100+'%',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
alignItems:'center',
justifyContent:'center',
position:'absolute',
bottom:this.state.bottom,
}}>
<Text style={styles.tekst}>{this.state.msg}</Text>
</Animated.View>
</View>
)
}
}
const styles=StyleSheet.create({
mainCont:{
flex:1,
backgroundColor:'gray'
},
container:{
height:50,
width:100+'%',
backgroundColor:'#000',
alignItems:'center',
justifyContent:'center',
position:'absolute',
bottom:0
}
});
AppRegistry.registerComponent('Animation', () => Animation);
谢谢。
答案 0 :(得分:0)
如果您查看官方文档:https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops
你会注意到语句“注意即使道具没有改变,React也可以调用这个方法,所以一定要比较当前和下一个值...”。我假设在一个父节点上进行了一些渲染调用,这使得在动画组件上调用重新渲染调用。因此,正在调用componentwillreceiveprops。我总是在使用上面的钩子时使用它:
componentWillReceiveProps(newprops) {
if(newprops.active === this.props.active) { return }
//if they are different do some stuff
}
}