V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  chnwillliu  ›  全部回复第 7 页 / 共 8 页
回复总数  160
1  2  3  4  5  6  7  8  
@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 模拟。
2021-10-20 07:18:04 +08:00
回复了 975779964 创建的主题 程序员 微信读书网页版如何 模拟 点击 下一页 按钮 ?
额 getElementsByClassName 返回的是数组,改成 querySelector

document.querySelector('.readerFooter_button').dispatchEvent(clickEvent);
2021-10-20 07:16:45 +08:00
回复了 975779964 创建的主题 程序员 微信读书网页版如何 模拟 点击 下一页 按钮 ?
因为在事件处理中他判断了事件是否有 clientX,没有的话就不执行后续动作了。

```js
var clickEvent = document.createEvent('mouseevent');
clickEvent.initMouseEvent('click', true, false, window, null, 100, 100, 100, 100);
document.getElementsByClassName('readerFooter_button').dispatchEvent(clickEvent);
```

这样就好啦。
2021-07-23 13:36:02 +08:00
回复了 pheyer 创建的主题 程序员 手机浏览器上的百度搜索框不能粘贴文字
百度用了一个 label 当 fake placeholder 盖在了 input 上,label 的 for 属性指向 input,所以点击可以聚焦到 input 上。但是粘贴需要长按呼出上下文菜单,而 label 并没有把长按事件代理到 input 上的功能。所以长按不但没有弹出菜单,反而导致了 input 失焦。输入框有值后 label 被 js 隐藏,因此长按直接按到了 input 上。

感觉这个 fake placeholder 就是个遗留产物,移动端哪里需要你去 fake 占位字符,还整出 bug 来。
2021-07-21 10:35:27 +08:00
回复了 mosade 创建的主题 TypeScript 关于 typescript 条件类型中的 extends
T extends P, 说明 T 类型 是 P 类型的一种,但是 T 类型可能比 P 类型存在更多的类型描述,即所谓 extends 的含义。Cat extends Animal, 但是 Cat 比 Animal 描述更确切,更具体。
2021-07-21 10:21:41 +08:00
回复了 4196 创建的主题 React RN 1.0 有新消息了
@chnwillliu 好像回复错了。尴尬。。
2021-07-21 10:19:24 +08:00
回复了 4196 创建的主题 React RN 1.0 有新消息了
@deathdealer 请继续关注(不要调台)
2020-12-15 06:52:21 +08:00
回复了 limy97 创建的主题 JavaScript 求判断刘海屏的解决方案 [JavaScript]
不需要 JS 判断啊,直接 CSS env 获取 safe-area 的边界。非要 JS 获取那你就 CSS 写 safe-area 的几个值到 root 节点上
然后 js 里 getComputedStyle / computedStyleMap 就能拿到这几个环境变量。

https://developer.mozilla.org/en-US/docs/Web/CSS/env()
2020-11-03 10:25:09 +08:00
回复了 shakukansp 创建的主题 JavaScript 记一次 RXjs 中 Subject 的使用经历
@shakukansp blur 总是会优先于 click 触发的,所以 click 内部判断有无 blur 引起的 request 在 pending 就可以。

不知道你的 A 框中的值不同会不会影响 C 框得到不一样的结果,如果会的话,C 有值再 enable B 按钮这种方案还是有问题。
2020-11-03 05:21:19 +08:00
回复了 shakukansp 创建的主题 JavaScript 记一次 RXjs 中 Subject 的使用经历
你这里的表单验证具体是什么操作?不应该是同步的操作么?
2020-11-03 05:13:35 +08:00
回复了 shakukansp 创建的主题 JavaScript 记一次 RXjs 中 Subject 的使用经历
感觉不需要 Subject 吧。

A blur 会触发验证并发请求,这个就它自己管好自己就 OK 。B click 需要检测当前有无正在 pending 的 A blur 引起的请求,有则等待,无则直接做自己该做的事。

不追求完全函数编程,就可以把 A blur 发请求的 observable 用变量保存起来。

大概这个意思:

```
let pendingRequest = null;

inputABlur$
.pipe(
switchMap(() => {
pendingRequest = httpClient.get('/url', data).pipe(share());
return pendingRequest;
}),
finallize(() => {
pendingRequest = null;
})
)
.subscribe();


buttonBClick$
.pipe(
switchMap(value => {
if (pendingRequest) {
return pendingRequest.pipe(mapTo(value));
}
return of(value);
}),
switchMap(() => httpClient.get('/url-a-c', dataAC))
)
.subscribe();


```
2020-10-16 06:58:41 +08:00
回复了 nurupo 创建的主题 CSS 初学 CSS,问一个比较基础的问题
负 margin 正解
1  2  3  4  5  6  7  8  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2042 人在线   最高记录 6543   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 23ms · UTC 01:08 · PVG 09:08 · LAX 18:08 · JFK 21:08
Developed with CodeLauncher
♥ Do have faith in what you're doing.