wax*_*ing 5 javascript knockout.js reactjs
我们有一个大型 Web 应用程序,主要使用 KnockoutJS 构建。我正在考虑是否有可能迁移到 React,但需要重写整个应用程序。我的想法是使用自下而上的方法:从一一替换基本构建块开始。
我受到之前一些工作的启发,在 KnockoutJS 绑定处理程序中调用 ReactDOM.render:
ko.bindingHandlers.react = {
init() {
return {controlsDescendantBindings: true};
},
update(element, valueAccessor) {
const {component, props} = valueAccessor();
ReactDOM.render(React.createElement(component, props), element);
}
};
Run Code Online (Sandbox Code Playgroud)
Knockout 有自己的依赖跟踪系统,因此每当某些数据发生变化时它就会调用 update 方法。
它工作完美,并且组件被重新渲染以反映数据的任何更改。然而,当数据在 React 事件处理程序中更新时,它就会崩溃。例如,该组件无法按预期工作:
const Input = function ({value}) {
return <input type="text"
value={value()}
onChange={e => value(e.target.value)}/>;
}
Run Code Online (Sandbox Code Playgroud)
注意:本例中的 value 是一个 ko.observable,像在事件处理程序中一样调用它会导致调用 bindingHandler 的 update 方法,进而调用 ReactDOM.render。但是,此渲染仅有效一次,之后组件将停止更新。
此 CodePen 中演示了该问题。单击该框并尝试输入一些内容。经过一次更新后,组件的函数将停止被调用。
编辑:我认为问题在于对 ReactDOM.render 的第二次调用(当用户在 onChange 处理程序中更新值时)不同步。这意味着 Knockout 的依赖项检测无法工作,并且任何后续调用都不再调用绑定处理程序的 update 方法。
这可以以某种方式规避吗?
正如我所猜测的,问题似乎是 ReactDOM.render 在某些情况下是异步的 - 在这种情况下,当从 React 中的事件处理程序调用时。
这意味着,如果您取消引用更新方法本身中依赖的任何可观察量,Knockout 的依赖项跟踪机制将按预期工作。这就是 Gawel1908 提出的修改使其起作用的原因 - 不是因为该值被“重置”,而是因为 props.value 被取消引用。
我决定改为使用约定:始终在 valueAccessor 本身中解开任何此类可观察量:
<div data-bind="react: { component: Input, props: { value: val(), setValue: val }}">
</div>
Run Code Online (Sandbox Code Playgroud)
并且不要将其解开到组件中:
const Input = function ({value, setValue}) {
return <input
type="text"
value={value}
onChange={e => setValue(e.target.value)}/>;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3531 次 |
| 最近记录: |