美文网首页
useCreation

useCreation

作者: skoll | 来源:发表于2020-09-09 11:18 被阅读0次

    useRef重新创建了实例,导致值会变

    class Foo{
      constructor(){
        this.data=Math.random()
      }
      data:number
    }
    
    export default function(){
      const [,setFlag]=useState({})
      const foo=useRef(()=>new Foo())
      let data=foo.current()
    
      function handleClick(){
        setFlag(1)
        console.log(data)
      }
      return (
        <>
          <p onClick={handleClick}>123</p>
        </> 
      )
    }
    
    
    const [,setFlag]=useState({})
      const foo=useRef(()=>new Foo()).current()
    
      function handleClick(){
        setFlag(1)
        console.log(foo)
      }
      return (
        <>
          <p onClick={handleClick}>123</p>
        </> 
      ) //这样也是不行
    线上版本还是编译出来都是会变得
    
    IMG20200908_173010.png

    第二个值之后就一直不变了。

    源码阅读

    1 .源码那里说的不会渲染,其实也是会走到里面,然后在第一次操作初始化之后,设置一个变量阻止下次进来的时候再次渲染。并不是不走进来。但是这里为什么前几次会走进来,后面就不会走进来,有点没搞懂


    IMG20200909_110711.png

    2 .从打印出来的log看第一次,第二次,第三次都走到了这里的逻辑,但是后面的点击发现就不会打印这个了,不知道这里是哪里阻止了后面的操作

    const [,setFlag]=useState(0)
      const foo = useCreation(() => new Foo(), []);
    
      function handleClick(){
        setFlag(s=>s+1)
        console.log('click')
      }
      return (
        <>
          <p onClick={handleClick}>{foo.data}</p>
        </> 
      )
    原来还是会进来,之不是我的之前的设置刷新的变量出了错,多点之后会不变
    const [,setFlag]=useState({})
      const foo = useCreation(() => new Foo(), []);
    
      function handleClick(){
        setFlag(1)
        console.log('click')
      }
      return (
        <>
          <p onClick={handleClick}>{foo.data}</p>
        </> 
      )
    //这尼玛还是官方的demo。。。
    

    代码

    import { useRef } from 'react';
    
    export default function useCreation<T>(factory: () => T, deps: any[]) {
      const { current } = useRef({
        deps,
        obj: undefined as undefined | T,
        initialized: false,
      });
      if(current.initialized === false || !depsAreSame(current.deps, deps)) {
        current.deps = deps;
        current.obj = factory();
        current.initialized = true;
        // 第一次之后再走到这里的情况只有满足后面的条件,依赖值发生变化才会重新计算值
      }
      return current.obj as T;
    }
    
    function depsAreSame(oldDeps: any[], deps: any[]): boolean {
      if (oldDeps === deps) return true;
      // 这一个没看懂,数组还能这么比吗?每次返回的都是false啊
      for (const i in oldDeps) {
        if (oldDeps[i] !== deps[i]) return false;
      }
      return true;
    }
    

    相关文章

      网友评论

          本文标题:useCreation

          本文链接:https://www.haomeiwen.com/subject/cwdjektx.html