NervJS / nerv

A blazing fast React alternative, compatible with IE8 and React 16.
https://nerv.aotu.io
MIT License
5.42k stars 267 forks source link

【讨论贴】给React加上强制刷新,是种什么体验? #163

Closed Eusen closed 4 years ago

Eusen commented 4 years ago

最近在写Taro项目,对React的状态管理感到头大,相比之下Vue和Angular的脏值检测让我觉得:真香。

基于上述考虑,我在 Taro(3.0) 做了一个基类,给让每个组件强制刷新(我知道有点憨,但有改进空间,比如:脏值检测),不多说了,上代码:

import {Component} from 'react'

export class Page<Props = any> extends Component {
  static isStartRender = false;
  static mountedPages: Component[] = [];

  static mount(component: Component) {
    this.mountedPages.push(component);
  }

  static unmount(component: Component) {
    this.mountedPages = this.mountedPages.filter(c => c !== component);
  }

  static startRender() {
    if (!this.isStartRender) {
      this.isStartRender = true;
      setInterval(() => {
        this.mountedPages.forEach(c => c.forceUpdate());
      }, 1000 / 60);
    }
  }

  props: Props;

  componentDidMount() {
    Page.mount(this);
  }

  componentWillUnmount() {
    Page.unmount(this);
  }
}

Page.startRender();

我知道肯定会有人说性能极差,不过是真的香,那感觉和Angular一模一样,随便改什么东西页面上秒刷新。

image

我发这个帖子主要是想和大家讨论一下,因为在我这个小项目中运行非常顺畅,我知道如果节点非常多的情况下,可能(我也不确定,大家可以试验一下)会卡顿,还需要再多实验一下。

大家也可以在项目中尝试一下,负面影响目前还没发现,但是秒刷新是真的香。

希望感兴趣的人可以多实践讨论,上面的代码优化方向是给每一个mounted的组件进行脏值检测,具体实现还没有想清楚,大家可以一起探讨一下~

希望管理员大大能容许在这里讨论(隔壁Taro不允许发这种帖了)


2020/7/2 12:35 更新

上面方式确实存在一个问题,就是 shouldComponentUpdatecomponentDidUpdate 无法正常使用了,因为它们不停在执行。这个问题在加上脏值检测之后应该可以缓解,这样可以保证组件只有在脏的时候才去刷新。


2020/7/2 13:35 更新

刚试了一下,如果所有页面和组件都继承这个类的话,大概可以支持250个节点同时刷新,再多就有点卡了。

但是如果只有页面对应的类继承的话,其他组件还是继承原来的Component,可以同时支持2000-3000个节点同时刷新。

所以我把上面的类改成了 Page,重点强调一下这个类只被页面对应的类继承即可。

export default class HomePage extends Page { 
    render() {
        return (
            // 这里引用的组件就不用继承上述类了
        )
    }
}
luckyadam commented 4 years ago

https://mobx.js.org/README.html

Eusen commented 4 years ago

@luckyadam 这个也不错,不过我这个方式和他还不太一样,最大的区别是我的方法不需要写任何额外的代码,就可以让页面中所有的子组件享受秒刷新。

Eusen commented 4 years ago

最新版本 trao-extras