基础知识

React 中 setInterval 会重复生成。需要在return 中清除。

  1. export default function App() {
  2. const [count, setCount] = useState(0)
  3. useEffect(() => {
  4. let timer = null;
  5. if(!timer){
  6. timer = setInterval(() => {
  7. setCount(count+1)
  8. },1000)
  9. }
  10. return () => {
  11. clearInterval(timer)
  12. }
  13. },[count])
  14. return (
  15. <div className="App">
  16. <h1>count value : {count}</h1>
  17. </div>
  18. );
  19. }

Hooks相关


UseState

useState 触发更新时。连续更改相同的值。如果是原始值,组件不会重新 render。
如果是引用类型的值。组件会重复渲染。

  1. import { useState } from "react";
  2. const UseState = () => {
  3. console.log("trigger count");
  4. const [count, setCount] = useState({ num: 1 });
  5. return (
  6. <>
  7. <button onClick={() => setCount((e) => ({ ...e, num: e.num + 1 }))}>
  8. increasement -{count.num}
  9. </button>
  10. <button onClick={() => setCount({ num: 0 })}>increasement -{0}</button>
  11. </>
  12. );
  13. };
  14. export default UseState;

React.memo

在react 中,当父组件渲染时,有可能造成子组件不必要的渲染,为了优化这种行为,我们可以使用
React.memo 来包裹子组件,确保只有 props 发生变化时才会重新渲染。

使用误区

在 React 中,如果子组件的有 children 属性的话。有两种情况第一种是你的children是一个文本节点,这时能正常工作。第二种是除了文本节点的HTML 元素,这时使用 React.memo 包裹是无效的。原因是这种情况下props.children是一个引用,所以会导致子组件总是重渲染。

useMemo

useMemo 是一个返回的是一个值。跟useCallback 类似。第一个参数是需要“缓存”的值,第二个参数是该组件重新渲染时的依赖值,如果依赖值发生变化,组件就重新渲染。

useCallback

useCallback返回一个函数,同样需要一个依赖值来决定函数是否渲染。常用的场景就是组件 执行了方法,那么依赖值发生变化,该方法/函数就会重新渲染。调用此方法的组件也会重新渲染。

useCallback通常跟React.memo一起使用,原因是组件传入的props 包括方法和值,值包括原始值和引用值。React.memo 只能保证 props 中全部是原始值时,组件不会重新渲染。如果是引用值,那么需要借助 useMemo 缓存复杂的引用值。props 包含执行的方法时。则需要使用 useCallback 来缓存方法。通过这三个api,才能精确的控制的组件的渲染。起到优化的作用。

  1. import "./styles.css";
  2. import PersonInfo from "./PersonInfo";
  3. import { useCallback, useState } from "react";
  4. export default function App() {
  5. const [age, setAge] = useState(18);
  6. const [name, setName] = useState("qujun");
  7. const handleChangeAge = useCallback(() => {
  8. setAge(age + 1)
  9. },[age])
  10. const changeName = useCallback(() => {
  11. const index = Math.floor(Math.random()*(-3) + 3);
  12. const val = ['中','国','你','好'].splice(index,1)
  13. setName(val[0])
  14. },[name])
  15. return (
  16. <div className="App">
  17. <h1>Hello CodeSandbox</h1>
  18. <PersonInfo handleClick={handleChangeAge} name={age}>
  19. changeAge
  20. </PersonInfo>
  21. <PersonInfo handleClick={changeName} name={name} >
  22. changeName
  23. </PersonInfo>
  24. </div>
  25. );
  26. }