【发布时间】:2017-12-11 04:48:05
【问题描述】:
我正在尝试在一个非常简单的循环 js 示例应用程序中将浏览器历史记录与包含在 onionify 状态存储中的状态同步。我从状态存储映射到历史没有问题,问题在于将 history.state 减少回状态存储。从本质上讲,我陷入了状态流相互流入的无限循环中,这会使浏览器崩溃。
import { run } from "@cycle/run";
import { div, button, p, makeDOMDriver } from "@cycle/dom";
import onionify from "cycle-onionify";
import { makeHistoryDriver } from "@cycle/history";
import xs from "xstream";
const main = (sources) => {
const popHistory$ = sources.history; // This is the problem...
const action$ = xs.merge(
sources.DOM.select(".decrement").events("click").map( () => -1 ),
sources.DOM.select(".increment").events("click").map( () => +1 ),
);
const state$ = sources.onion.state$;
const vdom$ = state$.map( state =>
div([
button(".decrement", "Decrement"),
button(".increment", "Increment"),
p(`Count: ${state.count}`)
])
);
const initReducer$ = xs.of( function initReducer() {
return {count: 0};
});
const updateReducer$ = action$.map( x => function reducer(prevState) {
return {count: prevState.count + x};
});
// this is where the inifinity loop starts
const historyReducer$ = popHistory$.map( history => function(prevState) {
return {count: history.state.count};
});
// You can't merge historyReducer$ here
const reducer$ = xs.merge(initReducer$, updateReducer$, historyReducer$);
const pushHistory$ = state$.map( state => ({
type: "push",
pathname: `/?count=${state.count}`,
state: state
}));
return {
DOM: vdom$,
onion: reducer$,
history: pushHistory$,
debug: popHistory$
}
};
const onionMain = onionify(main);
run(onionMain, {
DOM: makeDOMDriver("#main"),
history: makeHistoryDriver(),
debug: $ => $.subscribe({next: console.log})
});
我想我的问题是:有没有更简单的方法可以做到这一点?这里有帮助的操作员吗?我觉得我想做的事情基本上是不可能的。任何有用资源的答案或链接将不胜感激。
【问题讨论】:
-
根据代码,
historyReducer$改变洋葱状态,洋葱状态(通过pushHistory$)改变历史状态。这与流或 Cycle.js 无关,它只是在一个循环中相互改变的两件事。所以我需要进一步澄清:你想要实现什么功能? -
你说得对。这只是一个无限循环的问题。我对如何将历史源连接到状态以及状态返回到历史接收器感到困惑。
-
我通过不将历史源连接到历史接收器解决了这个问题,并且一切都按预期工作。我的目标是制作一个非常简单的路由示例,因为我找不到。我会发布我的答案,它可能对第一次学习循环客户端路由的人有用。
标签: javascript reactive-programming cyclejs