2017-12-14 132 views
6

Chciałbym poznać zalecany sposób (jeśli jest taki), aby obsłużyć przycisk Wstecz, reagując natywnie, gdy ma się do czynienia z platformą Android.Reaktywna funkcja obsługi kompleksowego przycisku tylnego przycisku

Wiem, że mogę zarejestrować słuchaczy na ekranie, ale ze względu na sposób działania nawigacji nie ma wyraźnego przepływu dla wiązania lub odłączania detektorów zdarzeń podczas nawigacji.

Do tej pory mam dwa pomysły.

1) Mogę zarejestrować jednego pojedynczego słuchacza i podejmując decyzje w oparciu o mój sklep redux. Oznacza to, że jeśli mam ekran, na którym mam wyskakujące okienko, które chcę zamknąć za pomocą przycisku Wstecz, muszę go odsłonić w sklepie. Zasadniczo do sklepu musi być podłączone dowolne elementy mojej aplikacji, na które chcę mieć wpływ przycisk Wstecz. Messy

2) Mogę zarejestrować słuchacza na ekranie. Z tego, co powiedziałem wcześniej, nie ma dostępnych niezawodnych haków w całym cyklu życia, więc będzie to musiało być ręczne na moim końcu, tzn. Zawsze powinienem wiedzieć, jakie działania będą nawigować na nowym ekranie i rozpinać słuchacza na danym ekranie przed nawigacją.

To jednak rozwiązuje połowę problemu. Podczas powrotu do ekranu należy ponownie powiązać słuchacza. Nie wiem, jak to zrobić, z wyjątkiem problemów związanych z componentWillRecieveProps i innymi. Nadal wydaje się brudny.

+0

co zrobiłem wcześniej, stworzyłem komponent o nazwie 'backButton', przeszły' navigation' obiekt, aby go jako parametr, i napisał logiczne zachowanie wewnątrz niego oddalić widok. – Ashraf

+0

To jest podobne do punktu 1 powyżej –

+0

Czy odnosisz się do przycisku powrotu sprzętu na Androida? – Corey

Odpowiedz

3

react-navigation obsługuje funkcję podstawowego przycisku Wstecz bez konieczności wykonywania pracy.

Jeśli chcesz trochę obsługi można spróbować react-navigation-addons biblioteka to daje 2 zdarzenia do słuchania niestandardowe: focus i blur więc można zarejestrować/wyrejestrować back button listeners kiedy te wydarzenia się zdarzyć.

To jest strategia 2) z twojego pytania, możesz użyć tego zamiast brakujących haków cyklu życia. Ale uważaj z tą biblioteką, że jest to eksperyment, więc przeczytaj notatkę przed jej użyciem. Byłoby to wyglądać mniej więcej tak:

class Screen extends Component { 
    handleBack =() => { 
    ... 
    } 

    screenFocus =() => { 
     // add back button listener or any other code you want to execute on screen focus 
     BackHandler.addEventListener('hardwareBackPress', this.handleBack); 
    } 

    screenBlur =() => { 
     // remove back button listener or add any other code you want to execute on screen blur 
     BackHandler.removeEventListener('hardwareBackPress', this.handleBack); 
    } 

    componentDidMount() { 
     this.props.navigation.addListener('focus', this.screenFocus); 
     this.props.navigation.addListener('blur', this.screenBlur); 
    } 

    componentWillUnmount() { 
     this.props.navigation.removeListener('focus', this.screenFocus); 
     this.props.navigation.removeListener('blur', this.screenBlur); 
    } 
    ... 
} 
1

React ma natywne API do obsługi sprzętu z powrotem działań na Androida i AppleTV. Dodajesz eventListender do komponentu BackHandler. Docs

Jeśli używasz react-navigation, możesz umieścić ten detektor zdarzeń w komponencie, który renderuje twój stos. Następnie możesz znaleźć ekran w stosie, który odpowiada twojemu stanowi nawigacji i zadzwonić do LeftButton onPress. Tutaj jest szorstka przykład -

const _RootContainer = (props) => { 
    const navigation = addNavigationHelpers({ 
    dispatch: props.dispatch, 
    state: props.nav, 
    }) 
    BackHandler.addEventListener('hardwareBackPress', function() { 
    const route = navigation.state.routes[navigation.state.index] 
    const screen = stack[route].screen 
    const navOptions = screen.navigationOptions({navigation}) 
     if (navOptions.headerLeft) { 
    navOptions.headerLeft.props.onPress() 
    } 
     return true; 
    }); 
    return (<View style={{ flex: 1 }}> 
    <AppNavigator 
     navigation={navigation} 
    /> 
    </View> 
)}