chnwillliu 最近的时间轴更新
chnwillliu

chnwillliu

V2EX 第 218858 号会员,加入于 2017-03-04 15:15:38 +08:00
chnwillliu 最近回复了
@nanxiaobei 不不不,它就是重点的。现如今的几大框架解决的最基本问题就是,怎么更新数据,数据更新了怎么通知 UI 更新。这是他们最大的区别,其他的东西,你有我也可以有,一个库的事。但是数据到 UI 的更新逻辑,是几大框架最大的壁垒。
@nanxiaobei 这么说吧, 在你的例子里如果是有个 if 条件判断才更新 count, 你的 render 调用是放 if 里吧?后来需求改了 加了 else ,else 里还有个 setTimeout 里面更新了 count, 是不是得记得 count 一赋值得记得调用 render ?那实际的业务场景可能更复杂,很多变量交织判断再赋值,你还跟踪什么时候要调用 render 吗?需求又突然改了,原本某个变量只是在逻辑里用了,后来在 UI 里也用到了,那还要捣回去检查这个变量的赋值操作后是否有 render 调用?那解决方案是什么?保底起见都调用一次 render ? onClick 里面 setTimeout 也得这么干不是?嵌套的异步都得记得调 render, 万一里面改了某个变量 UI 里用到了呢?
@nanxiaobei 你这个漏了,忘记调用 render 的话 UI 就不更新了,很容易出莫名其妙的 bug ,所以最后就成了到处调用 render ,比如 onClick 里套 setTimeout setTimeout 里再 xhr , xhr 回调里判断返回值,再更新 state , 最后你得记得调用你所谓的 render 函数。而 React 说的是你用我规定的方法更新 state ,更新 UI 的事我帮你干了你不用操心。


其实 Angular 的脏检查就是这个方法啦,Angular 会 hook 到所有可能的回调接口,你直接跟常规 js 一样改你的变量,Angular 帮你做脏检查 update UI , 是没有心智负担的。Svelte 的做法是编译插入代码以触发 UI update 逻辑。Vue 是 defineProperty / Proxy 做到你改 data 它帮你更新 UI.

而你的方案是需要使用者自己 call 一个方法来触发 UI 更新,漏了的结果就是 UI 和变量的值不同步,秉承多调用一次没什么大问题的想法,那结果就是每层异步逻辑都要记得调用这个更新方法,虽然有 async / await 会好些。

这就是我不明白的地方,你规避了 React 的缺点,但似乎又引入了更严重的问题。

个人鄙见哈。
@nanxiaobei React 的 setState 和你的 render 还是不一样的,setState 的理念是别直接赋值 state, 用 setState 更新,记住这点就好,当然同样的 set 完了马上 getState 的逻辑也要搞清。

而手动 render 带来的心智负担是,当逻辑复杂存在多层异步嵌套的时候或者更新 state 的逻辑在深层分支里的时候,你要时刻记得在恰当的时候手动调用 render ,最后指不定就成了不管事件回调里改没改 state, 末了都调用一次 render 吧。
@nanxiaobei https://reactjs.org/docs/react-component.html#forceupdate 我说的是这个 forceUpdate ,不是 DOM 的 forceUpdate 哈。class component 的 forceUpdate 其实也只是跳过 shouldComponentUpdate ,所以你的 useRender 本质上就是让 React 知道 View 更新了。你用 class component 来做的话,都不需要什么 useRender 。
不过也对,函数式组件本来就是会重新跑一边,哪怕你就 setState 更新了其中一个 state. 我的点是,既然都这么用 React 了,那就不要 hooks 了,原来的 class component 兴许改造起来更顺手。
@nanxiaobei 你这就是 forceUpdate 呀,只不过 hooks 版本没有 forceUpdate 要借用 useState 返回函数的 update.
const createRiC = (factory)=>{
return class extends React.Component {
constructor (props) {
super(props);
this.__render = factory ({
update: this.forceUpdate.bind(this)
})
}

render() {
return this.__render();
}
}
}

const Demo = createRiC(({update})=>{
let count = 0;
const onClick = () => {
count++;
update();
};

return () => {
return (
<>
<h1>{count}</h1>
<button onClick={onClick}>Click me</button>
</>
);
});

魔改的话,这样也能跑,不必用 hooks 改呀
这样每次 render 都要手动 forceUpdate ,state 完全不归 React 管,那为什么还要基于 React 魔改?而且还是用 hooks 魔改。你用 class component 魔改起来也简单一点啊,毕竟 forceUpdate onMounted 都直接给你了,不用你绕弯用 useState useEffect 模拟。
额 getElementsByClassName 返回的是数组,改成 querySelector

document.querySelector('.readerFooter_button').dispatchEvent(clickEvent);
关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2530 人在线   最高记录 5497   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 13ms · UTC 14:44 · PVG 22:44 · LAX 06:44 · JFK 09:44
♥ Do have faith in what you're doing.