2016-04-14 7 views
3

Ich habe ein Spiel Pilot mit React + Redux implementiert, und es funktioniert gut in einem normalen Browser (Web-Version).Wie React App mit Redux in Cordova richtig zu initialisieren - mapStateToProps nicht

Wenn mit Cordova (das Endziel) ausgeführt wird, stoppt es sofort, nachdem die Reduzierungen Daten verarbeitet haben (ein Token vom Server). Die Statusänderung wird nicht an die mapStateToProps-Methode im verbundenen Container übergeben. In der Webversion funktioniert es wie ein Zauber.

Es scheint, als ob die "Verbindung" nicht erfüllt wurde ... irgendwie. Der mapStateToProps wird nicht aufgerufen, nachdem die Reduzierer ihre Arbeit beendet haben, aber dies geschieht nur, wenn sie in Cordova ausgeführt werden!

Ich vermute, das Problem beginnt den ganzen Weg in den Start der App. Ich habe studiert und nach Varianten des obligatorischen Wartens auf das 'deviceready' Ereignis gesucht. Das ist mein index.jsx Code:

import React from "react"; 
import ReactDOM from "react-dom"; 
import {Provider} from "react-redux"; 
import {Router, Route, IndexRoute, useRouterHistory, hashHistory} from "react-router"; 
import {createHashHistory} from "history"; 
import App from "./components/app"; 
import Game from "./components/game"; 
import Frontpage from "./components/frontpage"; 
import {store} from "./store"; 

function startApp() { 
    ReactDOM.render(
    <Provider store={store}> 
     <Router history={hashHistory}> 
     <Route path="/" component={App}> 
      <IndexRoute component={Frontpage}/> 
      <Route path="game" component={Game}/> 
     </Route> 
     </Router> 
    </Provider> 
    , document.querySelector('.my-container') 
); 
} 

const url = document.URL; 
const isSmart = (url.indexOf("http://") === -1 && url.indexOf("https://")  === -1); 
const isRipple = (url.indexOf(":3000") !== -1); 

if (isSmart || isRipple) { 
    document.addEventListener('deviceready', startApp, false); 
} else { 
    startApp(); 

} 

Der "lästig" Container sieht wie folgt aus (frontpage.js):

import React, {Component} from "react"; 
import {connect} from "react-redux"; 
import * as actions from "../actions"; 
import {hashHistory} from "react-router"; 

class Frontpage extends Component { 

    componentWillMount() { 
    if (this.props.token) { 
     hashHistory.push("/game"); 
    } else { 
     this.props.fetchToken(this.props.handleMessageFromChannel); 
    } 
    } 

    componentWillUpdate(nextProps) { 
    if (nextProps.token) { 
     hashHistory.push("/game"); 
    } 
    } 

    render() { 
    return <div className="frontpage"></div> 
    } 
} 

function mapStateToProps(state) { 
    return { token: state.token }; 
} 

export default connect(mapStateToProps, actions)(Frontpage); 

und der Laden ist in store.js definiert:

import reducers from "./reducers/index"; 
import ReduxPromise from "redux-promise"; 
import {createStore, applyMiddleware} from "redux"; 

export const store = applyMiddleware(ReduxPromise)(createStore)(reducers); 

Der Token Minderer in Datei token_reducer.js:

import {FETCH_TOKEN} from "../actions/types"; 

export default function (state = null, action) { 
    switch (action.type) { 
    case FETCH_TOKEN: 
     return action.payload.data.token; 
    } 

    return state; 
} 

Bei Google- und SO-Suchanfragen konnte ich niemanden mit dem gleichen Problem finden. Ich werde gerne weitere Dateien posten, wenn es relevant ist ...?

Antwort

1

Der Fehler woanders ... bekam

Einer der anderen Reduzierungen war fest - oder nicht - und verursacht die Verarbeitung der Aktion zu stoppen. Es gab keine Warnungen oder Fehler in der Konsole, so dass es schwierig war, das Problem zu lokalisieren.

Warum das unterschiedliche Verhalten auf Cordova? Der andere Minderer schafft ein Eventsource-Objekt (zum Empfangen von Server gesendete Ereignisse) und pro „Schulbuch Muster“ Ich habe es geschaffen, so dass es das ursprüngliche Protokoll verwenden würde, sei es https oder http:

const eventSource = new EventSource("//192.168.1.2:8080/api/channel...); 
eventSource.onmessage = function(message) { 
    store.dispatch(handleMessageFromChannel(message.data)) 
}; 

aber dies wird nicht spielen Sie gut auf Cordova, da das Protokoll des geladenen JavaScript file: // ist, und es ist offensichtlich falsch, die EventSource in Richtung des Dateisystems des Geräts einzurichten.

Das sollte korrekten Code sein:

const eventSource = new EventSource("http://192.168.1.2:8080/api/channel...); 
eventSource.onmessage = function(message) { 
    store.dispatch(handleMessageFromChannel(message.data)) 
}; 

..., die für die Produktion eine korrekte URL und https vorzugsweise sein wird.

Verwandte Themen