javascript - 如何在 Cordova 中使用 redux 正确初始化 React 应用程序 - 未调用 mapStateToProps

标签 javascript cordova reactjs react-redux

我有一个使用 React + Redux 实现的游戏试点,它在常规浏览器(网络版)中运行良好。

当使用 Cordova 运行时(这是最终目标),它会在 reducer 处理完数据(来自服务器的 token )后立即停止。状态更改未传递到已连接容器中的 mapStateToProps 方法。在网络版本中,它就像一个魅力。

似乎“连接”还没有实现……不知何故。 reducer 完成工作后不会调用 mapStateToProps,但这只会在 Cordova 中运行时发生!

我怀疑问题是在应用程序启动时开始的。我研究并搜索了强制等待“设备就绪”事件的变体。这是我的 index.jsx 代码:

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();

}

“麻烦的”容器看起来像这样(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);

商店在 store.js 中定义:

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

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

token_reducer.js 文件中的 token reducer:

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;
}

通过 Google 和 SO 搜索,我找不到遇到同样问题的人。 如果相关,我很乐意发布更多文件...?

最佳答案

错误在别的地方...

其中一个 reducer 卡住了 - 或者失败了 - 导致 Action 处理停止。控制台中没有警告或错误,因此很难查明问题。

为什么在 Cordova 上有不同的行为? 另一个 reducer 创建一个 EventSource 对象(用于接收服务器发送的事件),并且根据我创建的“教科书模式”,它会使用原始协议(protocol),无论是 https 还是 http:

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

但这在 Cordova 上不会很好地发挥作用,因为加载的 JavaScript 的协议(protocol)是 file://,并且将 EventSource 建立到设备的文件系统显然是错误的。

正确的代码应该是:

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

...对于生产来说,这将是一个正确的 URL,最好是 https。

关于javascript - 如何在 Cordova 中使用 redux 正确初始化 React 应用程序 - 未调用 mapStateToProps,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36632062/

相关文章:

javascript - 如何从不同的窗口调用javascript?

android - Cordova 构建失败

android - 在 Phonegap/Cordova iOS 和 Android 中自动填充短信

javascript - 如何在react中更改material-ui Textfield标签样式

javascript - 如何让我点击的div后面的div

javascript - onChange 不适用于 React 和 select2

reactjs - 在react-redux中哪里存储socket连接?

javascript - 如何更改 react 中复选框项目的值? (更改sql中的一个值)

javascript - 如何以通用方式禁用 cookie,直到用户接受 cookie

javascript - 使用 Javascript 预防 WebSQL 注入(inject)