2017-04-18 5 views
0

私のテストアプリケーションでは、奇妙な動作に気付きました。 "componentWillReceiveProps"機能を持つ私のコンポーネントはダブルコールです。ボタンクリック後に一度だけ呼び出す必要がありますが、それは奇妙な順序で2倍です。 私は3つの要素を持っている: テスト - 出発成分 SetMessageは - テストから小道具を受信し、アニメーションコンポーネントに アニメーションを渡す - SetMessageから小道具を受信し、dispaly本物のネイティブの2倍のコールコンポーネント

クリックボタンコンポーネントと機能は次のように呼び出しをする必要がありますので、後:

Test-> SetMessage(関数:reciveProps-> setMsg) アニメーション(関数:reciveProps-> showMsg)。

しかし、私の場合には、次のとおりです。

テスト - > SetMessage(機能:reciveProps)、その後アニメーション(機能:reciveProps-> showMsg)、その後 SetMessage(機能:changeMsg)は、その後 アニメーション(機能:reciveProps-> showMsg)。

これは正常であればいいですか?そうでない場合、なぜそれが起こり、それを修正するのですか?

すべてのコードとログの画面が表示されません。

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); 

ログ画面: enter image description here

ありがとうございます。

答えて

0

あなたは、公式ドキュメントをチェックした場合:https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops

あなたは小道具が変更されていない場合でも、このメソッドを呼び出すことができリアクト文の」注意に気づくので、現在と次の値を比較することを確認します... "私はレンダリングのいくつかの呼び出しが、あなたのAnimationコンポーネントで呼び出される再レンダリング呼び出しを行う親の1つで行われていると仮定します。したがって、コンポーネントの受領現金が呼び出されています。私は常に上記のフックを使用するときにこれを使用します:

componentWillReceiveProps(newprops) { 
    if(newprops.active === this.props.active) { return } 
    //if they are different do some stuff 
    } 
} 
+0

ありがとうございます。 – Klick

関連する問題