2016-05-03 2 views
3

Manchmal wird der Titel des Navigation Headers durch den Inhalt der Navigationskarte bestimmt. Z.B. In der What's App sehen Sie den Benutzernamen und das Foto, wenn Sie sich im Chat-Fenster befinden.Navigation Experimentell: So ändern Sie den Navigationstitel basierend auf dem Inhalt der Navigationskarte

Ich frage mich, wie dies zu tun ist, da der NavigationHeader der Eltern der NavigationCard ist.

<NavigationAnimatedView 
      navigationState={navigationState} 
      style={styles.container} 
      onNavigate={(action) => { 
       if (action.type === 'back') { 
        navigateBack(); 
       } 
      }} 
      renderOverlay={this._renderHeader.bind(this)} 
      renderScene={props => (
       <NavigationCard 
        {...props} 
        key={props.scene.navigationState.key} 
        ref="sceneRef" 
        renderScene={this._renderScene.bind(this)} 
       /> 
      )} 
     /> 

    <NavigationHeader 
      {...props} 
      navigationState = {navigationState} 
      viewProps={props} 
      style={[styles.appbar]} 
      renderTitleComponent={() => this._renderTitle(route)} 
      renderLeftComponent={() => this._renderHeaderLeft(route)} 
      renderRightComponent={() => this._renderHeaderRight(route)} 
     /> 

ich versuchte, einen ref auf der NavigationCard Erstellen so kann ich die Komponente aufrufen, die Informationen enthalten, aber das ist noch in der renderTitleComponent Methode nicht zur Verfügung.

Antwort

1

Ich hatte das gleiche Problem. Soweit ich weiß, gibt es keine Best Practice, um dies dokumentiert irgendwo zu tun. Ich habe einen benutzerdefinierten Navigationsreduzierer hinzugefügt, der den Titel für die aktuelle Szene festlegt.

function CustomReducer(lastState, action) { 
    switch (action.type) { 
     case 'updateTitle': 
      let newState = {...lastState, children: lastState.children.slice()}; 
      newState.children[lastState.children.length - 1].title = action.title; 
      return newState; 

    } 
    return lastState; 
} 

Jetzt können Sie Sachen wie dies tun:

componentWillMount() { 
    this.props.onNavigate({type: 'updateTitle', title: 'Foo'}); 
} 

Ich mag nicht telefonieren OnNavigate für etwas, das eindeutig nicht Navigation verwandt ist, aber es ist extrem einfach und funktioniert gut so weit.

Ich würde gerne einige andere Ansätze auch sehen.

1

Der erste Teil ist in Ihrem onNavigate, die auf dieser Karte navigiert, sollten Sie einen Titel in Ihrem Zustand übergeben, die automatisch gezogen werden für Ihre Header-Komponente verwendet: this.props.onNavigate({key: 'NewView', title: myuser.Username})}

Der zweite Teil I sehen Sie, dass Sie überschreiben renderTitleComponent. Das bedeutet, dass Sie dafür verantwortlich sind, dass Sie den Titel selbst (oder andere Daten, die Sie möchten) weitergeben. Zum Glück kann man es immer noch aus Ihrer Szene lesen navigationState (genauso wie im Standard renderTitleComponent Code ausgeführt wird), durch so etwas wie dies zu tun:

renderTitleComponent={(props) => { 
    return <NavigationHeaderTitle> 
    {props.scene.navigationState.title 
    </NavigationHeaderTitle>; 
}} 

In diesem Fall können Sie sich in den Benutzer übergeben möchten in dem navigationState Objekt, so können Sie das Profilfoto auch ergreifen.

1

Meine Lösung für dieses Problem ist ziemlich einfach, aber ich bin mir nicht sicher, ob es nicht zu hacky ist. Das Einzige, was Sie ändern müssen, ist der Reduzierteil, damit Sie Änderungen an einem Ort behalten. Ich wechsle nur dynamisch title von Staat als PUSH/POP Aktion erscheint:

const initialState = { 
    index: 0, 
    routes: [ 
     {key: 'cities', title: 'Cities'}, 
    ], 
}; 

export const reducer = (state = initialState, action) => { 
    switch (action.type) { 
     case '@@redux/INIT': { 
      return {...state, title: state.routes[0].title}; 
     } 
     case actionTypes.PUSH: { 
      // some additional logic 
      const newState = {...state, title: action.newState.title}; 
      return NavigationStateUtils.push(newState, action.newState); 
     } 
     case actionTypes.POP: { 
      // some additional logic 
      const newState = {...state, title: state.routes[state.index - 1].title}; 
      return NavigationStateUtils.pop(newState); 
     } 
    } 
    return state; 
}; 

Bitte beachte, dass ich auf @@redux/INIT Aktion hören bin. Sie können diese ommit durch manuelle title zu initialState Einstellung:

0

Es funktioniert den Titel in den Minderer zu ändern. Beachten Sie, dass routes.slice() die Objekte innerhalb des Arrays nicht klont. Die folgende Funktion arbeitet mit der Standard-Header-Logik usw.

case t.CHANGE_ROUTE_TITLE:{ 

    let routes = state.routes.slice() 
    let i = routes.length - 1 
    routes[i] = { 
    ...routes[i], 
    title: action.payload, 
    searchPlaceholder: 'Zoek in ' + action.payload 
    } 

    return { 
    ...state, 
    index: routes.length - 1, 
    routes, 
    }; 
} 
Verwandte Themen