79. Hooks原理解析

79. Hooks原理解析

最简单的useState

例子

import React from "react";
import ReactDOM from "react-dom";
const rootElement = document.getElementById("root");

function App() {
  const [n, setN] = React.useState(0);
 
  return (
    <div>
      <p>{n}</p>
      <p>
        <button onClick={() => setN(n + 1)}>+1</button>
       
      </p>
    </div>
  );
}

ReactDOM.render(<App />, rootElement);

 

https://codesandbox.io/s/hook-6rpt3?from-embed

如何让两个useState不冲突

https://codesandbox.io/s/hook-6rpt3

useState不能写在if里

总结

每个函数组件对应一个React节点

每个节点保存着state和index

useState会读取state[index]

index由useState出现的顺序决定

setState会修改state,并触发更新

useRef

setN( )不会改变n的值。

两种操作:

1.点击+1再点击log---无bug //n:1

2.点击log再点击+1---有bug //n:0

问题:为什么log出了旧数据

https://codesandbox.io/s/usestate-u319x

Screen Shot 2022-03-08 at 9.11.44 AM

如果我希望有一个贯穿始终的状态,怎么做?办法很多

  • 全局变量

    • window.xxx即可,但太low了

  • useRef

    • useRef不仅可以用于div,还能用于任意数据

    • useRef例子

    • 强制更新的例子(不推荐使用)

  • useContext

    • useContext不仅能贯穿始终,还能贯穿不同组件

    • useContext例子

https://codesandbox.io/s/useref-r9yzw

useContext & 总结

useContext非常适合拿来切换主题

https://codesandbox.io/s/wizardly-grothendieck-ek0i5

createContext就是一个局部的上下文变量

总结

  • 每次重新渲染,组件函数就会执行

  • 对应的所有state都会出现“分身”

  • 如果你不希望出现分身

  • 可以用useRef/useContext

最后更新于

这有帮助吗?