2016-08-31 1 views
1

Ich verwende React-Native-Router-Flux zum Routing meiner App. Das Problem ist, dass es so aussieht, als wenn sich ein Redux-Zustand ändert, ALLE Komponenten unter dem Router werden neu gerendert, nicht nur die "aktuelle" Komponente.Verhindern, dass reactive-native-router-flux alle Komponenten rendert

können also sagen, ich habe zwei Komponenten unter dem Router: Register und Anmeldung und beide teilen sich die gleiche authenticationReducer. Wenn ein Authentifizierungsereignis (z. B. Benutzerregistrierung oder Anmeldung) fehlschlägt, möchte ich Fehlerwarnungen anzeigen.

Das Problem ist, dass wenn ein Fehler von einer der Komponenten ausgelöst wird, zwei Warnungen gleichzeitig angezeigt werden, eine von jeder Komponente. Ich nehme an, wenn ich mich gerade in der Registrierungsszene befinde, würde nur der Fehleralarm von der Register-Komponente angezeigt werden.

Es sieht jedoch so aus, als würden beide Komponenten immer dann rendern, wenn sich der Redux-Status ändert, und ich sehe 2 Warnungen (im folgenden Beispiel "Fehler von REGISTER" und "Fehler von SIGNIN").

Hier sind die Komponenten:

main.ios.js

export default class App extends Component { 
    render() { 
     return (
      <Provider store={store}> 
       <Router> 
        <Scene key='root'> 
         <Scene key='register' component={Register} type='replace'> 
         <Scene key='signin' component={SignIn} type='replace'> 
        </Scene> 
       </Router> 
      </Provider> 
     ); 
    } 
} 



Register.js

class Register extends Component { 
    render() { 
     const { loading, error } = this.props; 
     if (!loading && error) { 
      Alert.alert('Error from REGISTER'); 
     } 

     return <View>...</View>; 
    } 
} 

const mapStateToProps = (state) => { 
    return { 
     loading: state.get("authenticationReducer").get("loading"), 
     error: state.get("authenticationReducer").get("error"), 
    }; 
}; 

export default connect(mapStateToProps)(Register); 



SignIn.js

class SignIn extends Component { 
    render() { 
     const { loading, error } = this.props; 
     if (!loading && error) { 
      Alert.alert('Error from SIGNIN'); 
     } 

     return <View>...</View>; 
    } 
} 

const mapStateToProps = (state) => { 
    return { 
     loading: state.get("authenticationReducer").get("loading"), 
     error: state.get("authenticationReducer").get("error"), 
    }; 
}; 

export default connect(mapStateToProps)(SignIn); 

Wie ändere ich das so, dass nur die Meldung Registerfehler zeigt, wenn ich zur Zeit bin auf der Register-Szene, und vice versa?

Dank

Antwort

0

Aufgrund der Art und Weise reagieren-native-Router-Fluss funktioniert, werden alle vorherigen Seiten sind noch „offen“ und montiert. Ich bin mir nicht ganz sicher, ob diese Lösung wegen dieser seltsamen Eigenart funktionieren wird.

Ziemlich streng (und einfach) Regel zu folgen mit React: Keine Nebenwirkungen in render. Im Moment machen Sie gerade einen Nebeneffekt, nämlich Alert.alert(). Rendering kann einmal, zweimal oder mehrmals aufgerufen werden, bevor das Rendering ausgeführt wird. Dies wird jetzt dazu führen, dass die Warnung auch mehrfach auftaucht!

Versuchen Sie es in einem componentDidUpdate setzen und es zu den vorherigen Requisiten vergleichen, um sicherzustellen, dass es passiert nur einmal:

componentDidUpdate(prevProps) { 
    if (this.props.error && this.props.error !== prevProps.error) { 
    // Your alert code 
    } 
} 

Ich bin nicht davon überzeugt, dass dies auch tatsächlich funktionieren, da die Komponente noch aktualisiert weil es durch reaction-native-router-flux im Speicher gehalten wird, aber es wird zumindest weniger Macken haben.

+0

rufen Sie einfach die Pop-Funktion der Aktion des Routers Flusses reagieren. – AndrienPecson

0

Ich löste dies, indem ich einen ErrorContainer erstellte, um nach Fehlern zu suchen, und ihn mit einer Komponente verbunden, die react-native-simple-modal verwendet, um einen einzelnen Fehler modal in der App zu rendern.

Dieser Ansatz ist gut, weil Sie nur Fehlerlogik und einmal definierte Komponenten benötigen. Die Reactive-native-Simple-Modal-Komponente ist unglaublich einfach zu bedienen. Ich habe einen Fehlerspeicher, bei dem es sich um ein Array handelt, an das ich von überall aus Fehler senden kann. In den Containern mapStateToProps nehme ich einfach den ersten Fehler im Array (FIFO), so dass mehrere Fehlermodale einfach "gestapelt" werden, wenn Sie einander schließen, wird geöffnet, falls vorhanden.

Behälter:

const mapStateToProps = (
    state) => { 
    return { 
     error: state.errors.length > 0 ? state.errors[0] : false 
    }; 
}; 

Minderer:

export default function errors (state = [], action) { 
    switch (action.type) { 
     case actionTypes.ERRORS.PUSH: 
      return state.concat({ 
       type: action.errorType, 
       message: action.message, 
      }); 
     case actionTypes.ERRORS.POP: 
      return state.slice(1); 
     case actionTypes.ERRORS.FLUSH: 
      return []; 
     default: 
      return state; 
    } 
} 
Verwandte Themen