python教程分享React Hook 四种组件优化总结

前言

react hook 已成为当前最流行的开发范式,react 16.8 以后基于 hook 开发极大简化开发者效率,同时不正确的使用 react hook也带来了很多的性能问题,python教程分享React Hook 四种组件优化总结梳理基于 react hook 开发组件的过程中如何提高性能。

组件抽取

优化前

每次点击 increase 都会引起子组件 child 的渲染,哪怕子组件并没有状态变化

function before(){      console.log('demo1 parent')      let [count,setcount] = usestate(0)      let [name,setname] = usestate('-')      const handleclick = ()=>{          setcount(count+1)      }      const handleinput = (e)=>{          setname(e.target.value)      }      return (          <div>              <div classname='l50'>                  <label>计数器:</label>                  <span classname='mr10'>{count}</span>                  <button classname='ml10' onclick={handleclick}>increase</button>              </div>              <div classname='l50'>                  <label htmlfor="">改变子组件:</label>                  <input type="text" onchange={handleinput}/>              </div>              <hr />              <child name={name}/>          </div>      )  }  // 子组件  function child(props){      console.log('demo1 child')      return (          <div classname='l50'>              子组件渲染:{props.name}          </div>      )  }

React Hook 四种组件优化总结

优化后

只需要把 increase 抽取成独立的组件即可。此时点击按钮,子组件并不会渲染。

/**   * 优化后,increase提取以后,上下文发生变化,组件内   * @returns    */  function increase(){      console.log('child increase')      let [count,setcount] = usestate(0)      const handleclick = ()=>{          setcount(count+1)      }      return (          <div>              <div classname='l50'>                  <label>计数器:</label>                  <span classname='mr10'>{count}</span>                  <button classname='ml10' onclick={handleclick}>increase</button>              </div>          </div>      )  }  function after(){      console.log('demo1 parent')      let [name,setname] = usestate('-')      const handleinput = (e)=>{          setname(e.target.value)      }      return (          <div>              <increase/>              <div classname='l50'>                  <label htmlfor="">改变子组件:</label>                  <input type="text" onchange={handleinput}/>              </div>              <child name={name}/>          </div>      )  }  // 子组件  function child(props){      console.log('demo1 child')      return (          <div classname='l50'>              子组件渲染:{props.name}          </div>      )  }

memo 优化组件

同样基于上述优化前代码,如果不抽取组件,使用 memo 优化后,当点击按钮后,也不会触发二次渲染。

// 优化前  function aftermemo(){      console.log('demo1 parent')      let [count,setcount] = usestate(0)      let [name,setname] = usestate('-')      const handleclick = ()=>{          setcount(count+1)      }      const handleinput = (e)=>{          setname(e.target.value)      }      return (          <div>              <div classname='l50'>                  <label>计数器:</label>                  <span classname='mr10'>{count}</span>                  <button classname='ml10' onclick={handleclick}>increase</button>              </div>              <div classname='l50'>                  <label htmlfor="">改变子组件:</label>                  <input type="text" onchange={handleinput}/>              </div>              <child name={name}/>          </div>      )  }    // 子组件  const child = memo((props)=>{      console.log('demo1 child')      return (          <div classname='l50'>              子组件渲染:{props.name}          </div>      )  })

react.memo 语法

react.memo 为高阶组件,与 react.purecomponent相似。

function testcomponent(props){    // 使用 props 渲染  }  function areequal(prevprops,nextprops){    /*    如果把 nextprops 传入 render 方法的返回结果与    将 prevprops 传入 render 方法的返回结果一致则返回 true,    否则返回 false    */  }  export default react.memo(testcomponent,areequal)

与 class 组件中 shouldcomponentupdate() 方法不同的是,如果 props 相等,areequal 会返回 true;如果 props 不相等,则返回 false。这与 shouldcomponentupdate 方法的返回值相反。

usecallback 优化组件

如果已经用了 memo ,当遇到下面这种场景时,同样会触发子组件渲染。比如,给 child 绑定一个 handleclick ,子组件内部增加一个按钮,当点击子组件的按钮时,更改 count 值,即使没有发生 name 变化,也同样会触发子组件渲染,为什么?memo 不是会判断 name 变化了,才会更新吗?

function before(){      console.log('demo1 parent')      let [count,setcount] = usestate(0)      let [name,setname] = usestate('-')      const handleclick = ()=>{          setcount(count+1)      }      const handleinput = (e)=>{          setname(e.target.value)      }      const handlechange = ()=>{          setcount(count+1)      }      return (          <div>              <div classname='l50'>                  <label>计数器:</label>                  <span classname='mr10'>{count}</span>                  <button classname='ml10' onclick={handleclick}>increase</button>              </div>              <div classname='l50'>                  <label htmlfor="">改变子组件:</label>                  <input type="text" onchange={handleinput}/>              </div>              <child name={name} handleclick={handlechange}/>          </div>      )  }    // 子组件  const child = memo((props)=>{      console.log('demo1 child')      return (          <div classname='l50'>              子组件渲染:{props.name}              <button onclick={props.handleclick}>更改count</button>          </div>      )  })

React Hook 四种组件优化总结

并不是 memo 没有生效,是因为当状态发生变化时,父组件会从新执行,导致从新创建了新的handlechange 函数,而 handlechange 的变化导致了子组件的再次渲染。

优化后

点击父组件的increase按钮,更改了 count 值,经过 usecallback 包裹 handlechange 函数以后,我们会发现子组件不再渲染,说明每当父组件执行的时候,并没有创建新的 handlechange 函数,这就是通过 usecallback 优化后的效果。 即使我们点击子组件的按钮,也同样不会触发子组件的渲染,同样 count 会进行累加。

function after(){      console.log('demo1 parent')      let [count,setcount] = usestate(0)      let text = useref();      let [name,setname] = usestate('-')      const handleclick = ()=>{          setcount(count+1)      }      const handleinput = (e)=>{          setname(e.target.value)      }      const handlechange = usecallback(()=>{          // 为了让 count 能够累加,我们使用ref 获取值          let val = parseint(text.current.textcontent);          setcount(val+1)      },[])      return (          <div>              <div classname='l50'>                  <label>计数器:</label>                  <span classname='mr10' ref={text}>{count}</span>                  <button classname='ml10' onclick={handleclick}>increase</button>              </div>              <div classname='l50'>                  <label htmlfor="">改变子组件:</label>                  <input type="text" value={name} onchange={handleinput}/>              </div>              <child name={name} handleclick={handlechange}/>          </div>      )  }

React Hook 四种组件优化总结

usecallback 作用

// 用法  usecallback(()=>{    // to-do  },[])    // 示例  function app(){    // 点击按钮调用此函数,但返回被缓存    const onclick = usecallback(() => {      console.log('我被缓存了,怎么点击都返回一样');    }, []);      return (       <button onclick={onclick}>点击</button>    );  }
  • usecallback 接收 2 个参数,第一个为缓存的函数,第二个为依赖值
  • 主要用于缓存函数,第二次会返回同样的结果。

usememo 优化

我们定义了一个total函数,内部使用 1 填充了100次,通过 reduce 计算总和,经过测试发现点击 increase按钮后,只会执行 total1 ,不会执行 total2,假设total计算量巨大,就会造成内存的浪费,通过 usememo 可以帮我们缓存计算值。

function before(){      console.log('demo1 parent')      let [count,setcount] = usestate(0)      const handleclick = ()=>{          setcount(count+1)      }      const total1 = ()=>{          console.log('计算求和1')          let arr = array.from({ length:100 }).fill(1)          return arr.reduce((prev,next)=>prev+next,0)      }      // 缓存对象值      const total2 = usememo(()=>{          console.log('计算求和2')          let arr = array.from({ length:100 }).fill(1)          return arr.reduce((prev,next)=>prev+next,0)      },[count])      return (          <div>              <div classname='l50'>                  <label>计数器:</label>                  <span classname='mr10'>{count}</span>                  <button classname='ml10' onclick={handleclick}>increase</button>              </div>              <div>                  <label>总和:</label>                  <span>{total1()}</span>                  <span>{total2}</span>              </div>          </div>      )  }

React Hook 四种组件优化总结

usememo 语法

const memoizedvalue = usememo(() => computeexpensivevalue(a, b), [a, b]);
  • 传入一个函数进去,会返回一个 memoized 值,需要注意的是,函数内必须有返回值
  • 第二个参数会依赖值,当依赖值更新时,会从新计算。

usecallback 和 usememo 区别

他们都用于缓存,usecallback 主要用于缓存函数,返回一个 缓存后 函数,而 usememo 主要用于缓存值,返回一个缓存后的值。

到此这篇关于react hook 四种组件优化总结的文章就介绍到这了,更多相关react hook 组件优化内容请搜索<猴子技术宅>以前的文章或继续浏览下面的相关文章希望大家以后多多支持<猴子技术宅>!

需要了解更多python教程分享React Hook 四种组件优化总结,都可以关注python教程分享栏目—猴子技术宅(www.ssfiction.com)

本文来自网络收集,不代表猴子技术宅立场,如涉及侵权请点击右边联系管理员删除。

如若转载,请注明出处:https://www.ssfiction.com/pythons/1187938.html

(0)
上一篇 21小时前
下一篇 21小时前

精彩推荐

发表评论

您的电子邮箱地址不会被公开。