我有一个使用 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/