Подтвердить что ты не робот

Правильный способ навигации с помощью React Native, Redux и Navigator

У меня есть приложение React Native, использующее среду Redux, и я использую компонент Navigator для обработки навигации. У меня было немного проблем с работой навигации, и я не могу найти хороших примеров того, как это сделать правильно, поэтому я ищу какую-то помощь и разъяснения.

Вот суть того, что у меня сейчас есть, но я не знаю, правильно ли я делаю это:

Корневой компонент

...
renderScene(route, navigator) {
    console.log('RENDER SCENE', route);
    const Component = route.component;
    return (
        <Component navigator={navigator} route={route} {...this.props} />
    )
}

render() {
    return (
        <Navigator
            renderScene={(route, nav) => this.renderScene(route, nav)}
            initialRoute={{ name: 'Signin', component: Signin }} />
    )
}

Компонент Signin

...
componentWillReceiveProps(nextProps) {
    if (!this.props.signedIn && nextProps.signedIn) {
        console.log('PUSHING TO MAIN');
        nextProps.navigator.push({ name: 'Main', component: Main });
    }
}

Вопросы:

1: Моя первая мысль здесь состоит в том, что я, вероятно, должен переместить код navigator.push в действие. Однако есть ли componentWillReceiveProps подходящее место для вызова действия? Когда компонент Signin загружается, он запускает действие для входа в пользователь, если у них уже есть активный сеанс. По умолчанию они не подписаны, поэтому, когда появляются следующие реквизиты, я проверяю, изменилось ли это значение, а затем нажмите на Main.

2: В моем журнале консоли сразу после записи "PUSH TO MAIN" я вижу два журнала "RENDER SCENE":

[info] 'RENDER SCENE', { name: 'Signin', component: [Function: Signin] } (EXPECTED)
[info] 'PUSHING TO MAIN'
[info] 'RENDER SCENE', { name: 'Signin', component: [Function: Signin] } (WHY?)
[info] 'RENDER SCENE', { name: 'Main', component: [Function: Main] }

Мне любопытно, почему RENDER SCENE вызывается дважды (первый из них является компонентом Signin), если я нажимаю только компонент Main.

Изначально в методе componentWillReceiveProps я проверял только:

if (nextProps.signedIn) {
    nextProps.navigator.push({ name: 'Main', component: Main });
}

но это привело к тому, что компонент Main был нажат дважды.

4b9b3361

Ответ 1

ПРИМЕЧАНИЕ. Ниже приведена ссылка GitHub ниже, в комментариях автор предложил react-native-router-flux, который является тем же автор.

Я только что добавил поддержку Redux, с моим новым компонентом https://github.com/aksonov/react-native-redux-router, что делает навигацию довольно простой, например вызов Actions.login

Ответ 2

Это не редукционная реализация, но для маршрутизации я нашел, что action-native-router-flux действительно полезен.

Вы можете делать такие вещи, как call

Actions.login 

чтобы перейти к окну входа. Маршруты определяются в вашем индексном файле и имеют необязательные схемы для определения элементов навигации.

https://github.com/aksonov/react-native-router-flux

Ответ 3

1) Да, переместите его в метод, componentWillReceiveProps, вероятно, неверен. Его трудно реорганизовать эту часть для вас, поскольку у меня не было бы такой логики из этого метода на этом компоненте, т.е. SigninComp должен получить состояние того, имеет ли он сеанс аутентификации или нет (и не понимает его для себя). Это приводит к тому, что он обрабатывается без причины; так как если он зарегистрирован в вас, перенаправление. Я лично сделал бы эту проверку в renderScene, так как навигатор будет передан, вы можете просто сделать push/pop для дочерних компонентов и обработать всю вашу логику в одном renderScene.

2) См. стек навигации как колоду карт. Когда вы устанавливаете сцену, это одна карта, но когда вы ее нажимаете, она добавляет еще одну карту в кучу. Поэтому, когда вы нажимаете и имеете две карты, он проверяет, чтобы все карты были обращены вверх и визуализированы так, что когда вы нажимаете назад или поп, он возвращается к завершенной карте или сцене. Представьте, что вы сразу же нажмете 5 сцен в стек. Поэтому, когда вы меняете стек, он проверяет, чтобы все, что было сделано и готово для этой кнопки возврата. Лично я не считаю это оптимальным (но это необходимо, поскольку вы можете передавать разные свойства с каждой выбранной вами сценой).

Вероятно, вы можете изменить эту строку на:

    renderScene={this.renderScene}

Ответ 4

Question1:
Я рекомендую обработать логику навигатора в методе shouldComponentUpdate, как показано ниже,

   shouldComponentUpdate(nextProps, nextState){

    if(nextProps.isLoggedIn != this.props.isLoggedIn && nextProps.isLoggedIn === true){
        //will redirect
        // do redirect option

        return false;
    }

    return true;
}

Вопрос 2:
Я думаю, что это ошибка реакции-родной.