Routes.js не работает должным образом, когда казалось, неиспользуемые mapStateToProps удалены - PullRequest
0 голосов
/ 16 мая 2018

Я в основном чищу свой код прямо сейчас и нашел что-то странное, я нашел mapStateToProps и connect, которые нигде не используются в этом файле:

import React from 'react';
import { Scene, Router, ActionConst, Stack } from 'react-native-router-flux';
import { connect } from 'react-redux';                  //HERE
import { AsyncStorage } from 'react-native';

//import components for scenes
import Splash from '../components/Splash/Splash';
import Login from '../modules/auth/scenes/Login';
import Home from '../modules/home/scenes/Home';
import itemDescription from '../modules/home/scenes/itemDescription';
import About from '../modules/home/scenes/About';
import Setting from '../modules/home/scenes/Setting';
import NavDrawer from '../modules/home/components/NavDrawer';

//Import Store, actions
import store from '../redux/store'
import * as t from '../modules/auth/actionTypes';

export const mapStateToProps = state => ({                      //HERE
    isLoggedIn: state.authReducer.isLoggedIn 
});

class Routes extends React.Component {
    constructor() {
        super();
        this.state = {
            isReady: false,
            isLoggedIn: false,
            userName:""
        }
    }

    componentDidMount() {
        //load token from async and put it in redux's state
        AsyncStorage.getItem('token').then((data) => {
            setTimeout(() => {
                if (data !== null) {
                    this.setState({ isReady: true, isLoggedIn: true });
                    store.dispatch({ type: t.LOGGED_IN, token: data });
                }
                else {
                    this.setState({ isReady: true, isLoggedIn: false })
                    store.dispatch({ type: t.LOGGED_OUT });
                }
            }, 5000)
        });

        //load username from async storage and put it in route's state to be passed to drawer as props
        AsyncStorage.getItem('username').then(name => {
            this.setState({ userName: name.charAt(0).toUpperCase() + name.slice(1) });
        }); 
    }

    render() {
        if (!this.state.isReady)
            return <Splash />
        return (
            <Router>
                <Scene key="root" hideNavBar>
                    <Stack key="Auth" initial={!this.state.isLoggedIn}>
                        <Scene key="Login" hideNavBar component={Login} title="Login" />
                    </Stack>
                    <Stack key="Main" initial={this.state.isLoggedIn}>
                        <Scene drawer key="NavDrawer" hideNavBar contentComponent={()=><NavDrawer username={this.state.userName}/>} type={ActionConst.REPLACE} panHandlers={null}>
                            <Scene key="homeTab" title="Home" drawerLockMode={'locked-closed'}>
                                <Scene key="Home" hideNavBar component={Home} title={"Home"} />
                                <Scene key="itemDescription" hideNavBar component={itemDescription} title="Item Description" back />
                            </Scene>
                            <Scene key="aboutTab" title="About" drawerLockMode={'locked-closed'}>
                                <Scene key="About" hideNavBar component={About} title={"About"} />
                            </Scene>
                            <Scene key="settingTab" title="Settings" drawerLockMode={'locked-closed'}>
                                <Scene key="Setting" hideNavBar component={Setting} title={"Setting"} />
                            </Scene>
                        </Scene>
                    </Stack>
                </Scene>
            </Router>
        )
    }
}

export default connect(mapStateToProps)(Routes)               //HERE

Я был почти уверен, что они были из моей ранней разработки, которую я еще не удалил, однако, когда я попытался удалить эти 3 отмеченные строки и просто экспортировать маршруты по умолчанию самостоятельно, произошло несколько странных вещей:

  1. Клавиатура не исчезает после входа в систему

  2. Данные главного экрана, которые зависят от токена, хранящегося в состоянии избыточности, неожиданно не были получены (выборка не удалась)

  3. имя пользователя не загружается в ящик.

Насколько я знаю, mapStateToProps просто используется для сопоставления состояния избыточности с реквизитом связанного (с использованием connect) компонента, чтобы компонент мог получить к ним доступ.

Это должен быть механизм только для чтения, потому что я устанавливаю состояние редукса, используя store.dispatch в моем componentDidMount

Какими будут ваши догадки относительно того, почему это происходит? Я здесь что-то не так понимаю?

Честно говоря, у меня нет идей, где искать: (

Заранее спасибо за любые идеи!

ОБНОВЛЕНИЕ: Я обнаружил, что store.dispatch в приведенном выше фрагменте не обновляет токен вовремя, когда я удаляю mapStateToProps по какой-то причине, что делает мой Home неспособным получать данные из его componentDidMount(), потому что токен был все еще нулевым. Однако на следующей итерации жизненного цикла Home журнал консоли показывает, что токен был обновлен, но componentDidMount не вызывался после обновления, а раньше. остается вопрос, почему mapStateToProps имеет значение в этом сценарии?

1 Ответ

0 голосов
/ 16 мая 2018

после некоторой регистрации консоли во всем приложении, я наконец-то знаю причину, по которой это mapStateToProps имеет значение в этом случае.Таким образом, похоже, что сценарий был таким:

с mapStateToProps:

маршрутизация токена загрузки -> диспетчерский токен для сохранения и начала загрузки дома -> home componentDidMount сработал, но токенвсе еще ноль, потому что отправка не выполнена -> как только отправка выполнена, маршруты перемонтированы, потому что подписка на mapStateToProps, которая обновляется с отправкой -> home, была перезагружена, на этот раз токен

без:

направляет токен загрузки -> токен отправки для сохранения и запуска загрузки дома -> home componentDidMount сработал, но токен все еще нулевой, поскольку отправка не выполнена -> после завершения отправки, маршруты НЕ переустанавливаются, потому что он не подписывается на mapStateToProps, который обновляется с отправкой -> home не перезагружается

Так что, похоже, мое приложение работало, но по совершенно неправильной причине !!

Итак, после того, как я удалил mapStateToProps, чтобы сделать мое приложение логически здоровым, оно сводится к этим двум последовательным строкам из фрагмента в моей question:

this.setState({ isReady: true, isLoggedIn: true });
store.dispatch({ type: t.LOGGED_IN, token: data });

Эти две строки в гонке , и последовательность была отключена для начала, я должен был сначала dispatched затем установить состояние в isReady:true, чтобыимеет больше смысла, чем приведенный выше фрагмент, потому что как я могу сказать «эй, вы можете закрыть экран-заставку и начать загрузку домой», когда я даже не отправил токен в магазин!

НО даже после этого эти 2линии по-прежнему участвуют в гонке, потому что они обе являются асинхронными операциями, так что теперь моя единственная проблема - как решить эту race condition, что гораздо проще понять!: D

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...