如何在 Cordova 中使用 redux 正确初始化 React 应用程序 - 未调用 mapStateToProps
How to properly initialize React app with redux in Cordova - mapStateToProps not called
我有一个用 React + Redux 实现的游戏试点,它在普通浏览器(网络版)中工作得很好。
当 运行 Cordova(这是最终目标)时,它会在 reducer 处理完数据(来自服务器的令牌)后立即停止。状态更改未传递到已连接容器中的 mapStateToProps 方法。在网络版中,它就像一个魅力。
似乎 "connect" 还没有完成……不知何故。 reducer 完成工作后不会调用 mapStateToProps,但这只会在 Cordova 中 运行 时发生!
我怀疑问题是在应用程序启动时一直出现的。我已经研究并搜索了强制等待 'deviceready' 事件的变体。这是我的 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();
}
"troublesome" 容器如下所示 (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 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;
}
从 Google 和 SO 搜索中,我找不到有同样问题的人。
如果相关,我很乐意 post 更多文件...?
错误出在其他地方...
其中一个减速器卡住了——或者失败了——导致动作处理停止。控制台中没有警告或错误,因此很难查明问题所在。
为什么在 Cordova 上有不同的行为?
另一个减速器创建一个 EventSource 对象(用于接收服务器发送的事件)并且根据 "school book patterns" 我创建它所以它会使用原始协议,无论是 https 还是 http:
const eventSource = new EventSource("//192.168.1.2:8080/api/channel...);
eventSource.onmessage = function(message) {
store.dispatch(handleMessageFromChannel(message.data))
};
但是这在Cordova上玩的不好,因为加载的JavaScript的协议是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。
我有一个用 React + Redux 实现的游戏试点,它在普通浏览器(网络版)中工作得很好。
当 运行 Cordova(这是最终目标)时,它会在 reducer 处理完数据(来自服务器的令牌)后立即停止。状态更改未传递到已连接容器中的 mapStateToProps 方法。在网络版中,它就像一个魅力。
似乎 "connect" 还没有完成……不知何故。 reducer 完成工作后不会调用 mapStateToProps,但这只会在 Cordova 中 运行 时发生!
我怀疑问题是在应用程序启动时一直出现的。我已经研究并搜索了强制等待 'deviceready' 事件的变体。这是我的 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();
}
"troublesome" 容器如下所示 (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 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;
}
从 Google 和 SO 搜索中,我找不到有同样问题的人。 如果相关,我很乐意 post 更多文件...?
错误出在其他地方...
其中一个减速器卡住了——或者失败了——导致动作处理停止。控制台中没有警告或错误,因此很难查明问题所在。
为什么在 Cordova 上有不同的行为? 另一个减速器创建一个 EventSource 对象(用于接收服务器发送的事件)并且根据 "school book patterns" 我创建它所以它会使用原始协议,无论是 https 还是 http:
const eventSource = new EventSource("//192.168.1.2:8080/api/channel...);
eventSource.onmessage = function(message) {
store.dispatch(handleMessageFromChannel(message.data))
};
但是这在Cordova上玩的不好,因为加载的JavaScript的协议是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。