【发布时间】:2020-02-20 09:51:34
【问题描述】:
我们有一个主要使用 KnockoutJS 构建的大型 Web 应用程序。我正在研究是否有可能迁移到 React,但需要重写整个应用程序。我的想法是使用自下而上的方法:从一个个替换基本构建块开始。
我受到prior work 的启发,在 KnockoutJS 绑定处理程序中调用 ReactDOM.render:
ko.bindingHandlers.react = {
init() {
return {controlsDescendantBindings: true};
},
update(element, valueAccessor) {
const {component, props} = valueAccessor();
ReactDOM.render(React.createElement(component, props), element);
}
};
Knockout 有自己的依赖跟踪系统,所以每当数据发生变化时,它都会调用 update 方法。
它完美地工作,并且组件被重新渲染以反映对数据的任何更改。但是,当数据在 React 事件处理程序中更新时,它会崩溃。例如,此组件无法按预期工作:
const Input = function ({value}) {
return <input type="text"
value={value()}
onChange={e => value(e.target.value)}/>;
}
注意:本例中的 value 是一个 ko.observable,像在事件处理程序中一样调用它会导致 bindingHandler 的 update 方法被调用,进而调用 ReactDOM.render。但是,此渲染只工作一次,之后组件停止更新。
The issue is demonstrated in this CodePen。单击该框并尝试输入一些内容。一次更新完成后,组件的函数停止被调用。
编辑:我认为问题在于对 ReactDOM.render 的第二次调用(当用户在 onChange 处理程序中更新值时)不是同步的。这意味着 Knockout 的依赖检测无法工作,任何后续调用都不再调用绑定处理程序的更新方法。
这可以通过某种方式规避吗?
【问题讨论】:
标签: javascript reactjs knockout.js